[jira] Created: (OFBIZ-2842) Add mocked unit test framework

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

[jira] Created: (OFBIZ-2842) Add mocked unit test framework

Nicolas Malin (Jira)
Add mocked unit test framework
------------------------------

                 Key: OFBIZ-2842
                 URL: https://issues.apache.org/jira/browse/OFBIZ-2842
             Project: OFBiz
          Issue Type: New Feature
          Components: ALL COMPONENTS
    Affects Versions: SVN trunk
            Reporter: Bob Morley


Add the ability to create "true" unit tests -- ones that only test the confines of the method itself and using mocking techniques and dependency injection.  This focuses the unit test on the actual code in the method and makes the assumption that other methods have been properly tested and will work.  This does not suggest that there is not also value in unit tests that test more of an integration between components (such as a test that will actually invoke services using a the real dispatcher and manipulate entities with the real delegator).

The goal of this will be to make it easy and very quick to test java-based methods (initial focus on services) along with not having to start an ofbiz container creating a suite of very quick method focused unit tests.

I have attached a first pass at some of the base classes and a sample of a "mostly complete" unit test for the DateDimensionServices class (which has one method).  Looking for feedback on this approach, potential for community collaboration, and potential buy-in.  Some other things that are still to be done --

- more samples
- integration into ant build
- solution to the "static worker" issue
- UtilResourceBundle solution (I have it partially commented out)
- easy verification of service interface adherence (servicedef existance & IN/OUT validation)
- potential for GenericEntity get/set validation (verify entitydef adherence) (may not want to do this)
- investigate potential for mocked simple methods
- ant driven code coverage metrics


--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply | Threaded
Open this post in threaded view
|

[jira] Updated: (OFBIZ-2842) Add mocked unit test framework

Nicolas Malin (Jira)

     [ https://issues.apache.org/jira/browse/OFBIZ-2842?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Bob Morley updated OFBIZ-2842:
------------------------------

    Attachment: mockito-all-1.8.0-rc2.jar
                OFBIZ-2842.patch

Mockito has been chosen for this work because it is simplistic and it uses the MIT license.  Not sure if I should be attaching the file here or not; but you will have to place this in the base/lib to honor the classpath.

> Add mocked unit test framework
> ------------------------------
>
>                 Key: OFBIZ-2842
>                 URL: https://issues.apache.org/jira/browse/OFBIZ-2842
>             Project: OFBiz
>          Issue Type: New Feature
>          Components: ALL COMPONENTS
>    Affects Versions: SVN trunk
>            Reporter: Bob Morley
>         Attachments: mockito-all-1.8.0-rc2.jar, OFBIZ-2842.patch
>
>
> Add the ability to create "true" unit tests -- ones that only test the confines of the method itself and using mocking techniques and dependency injection.  This focuses the unit test on the actual code in the method and makes the assumption that other methods have been properly tested and will work.  This does not suggest that there is not also value in unit tests that test more of an integration between components (such as a test that will actually invoke services using a the real dispatcher and manipulate entities with the real delegator).
> The goal of this will be to make it easy and very quick to test java-based methods (initial focus on services) along with not having to start an ofbiz container creating a suite of very quick method focused unit tests.
> I have attached a first pass at some of the base classes and a sample of a "mostly complete" unit test for the DateDimensionServices class (which has one method).  Looking for feedback on this approach, potential for community collaboration, and potential buy-in.  Some other things that are still to be done --
> - more samples
> - integration into ant build
> - solution to the "static worker" issue
> - UtilResourceBundle solution (I have it partially commented out)
> - easy verification of service interface adherence (servicedef existance & IN/OUT validation)
> - potential for GenericEntity get/set validation (verify entitydef adherence) (may not want to do this)
> - investigate potential for mocked simple methods
> - ant driven code coverage metrics

--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply | Threaded
Open this post in threaded view
|

[jira] Commented: (OFBIZ-2842) Add mocked unit test framework

Nicolas Malin (Jira)
In reply to this post by Nicolas Malin (Jira)

    [ https://issues.apache.org/jira/browse/OFBIZ-2842?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12752175#action_12752175 ]

Philipp Hoppen commented on OFBIZ-2842:
---------------------------------------

Hi Bob

In our OFBIz-projects, we like to have automated unit-tests running on a CruiseControl-server. Unfortunately, as OFBIz unit-tests are not directly called from a build script, the surrounding build process will assume a "successful" build even when the tests failed.

I guess using a Mock framework and then calling the tests from the build script is the right solution. I checked out Mockito and it seems to do the job quite well.

We have lots of minilang-code, so i experimented around in this area. Here is the code to call a minilang service:

        Map simpleMethods = SimpleMethod.getSimpleMethods("file:" + pathToSimpleMethods, simpleMethodName, null);
        SimpleMethod simpleMethod = (SimpleMethod) simpleMethods.get(simpleMethodName);
        simpleMethod.setUseTransaction(false);
        MethodContext methodContext = new MethodContext(dctx, context, null);
        simpleMethod.exec(methodContext);


SimpleMethod-objects try to aquire transactions, and this resulted in exceptions:

java.lang.IllegalStateException: Could not find transaction factory class name definition

Therefore, i added a setUseTransaction(boolean useTransaction) to the SimpleMethod class. It tries to commit a transaction no matter if useTransaction is false, so i added  an if-block around the commit-code so it only runs if useTransaction is true.

I had to write quite a lot "when(delegator...).ThenReturn(...)"-statements until i finally got a very simple minilang service running, but it works.

I hope to find some more time to experiment around.

What exactly do you mean by "UtilResourceBundle solution"?


> Add mocked unit test framework
> ------------------------------
>
>                 Key: OFBIZ-2842
>                 URL: https://issues.apache.org/jira/browse/OFBIZ-2842
>             Project: OFBiz
>          Issue Type: New Feature
>          Components: ALL COMPONENTS
>    Affects Versions: SVN trunk
>            Reporter: Bob Morley
>         Attachments: mockito-all-1.8.0-rc2.jar, OFBIZ-2842.patch
>
>
> Add the ability to create "true" unit tests -- ones that only test the confines of the method itself and using mocking techniques and dependency injection.  This focuses the unit test on the actual code in the method and makes the assumption that other methods have been properly tested and will work.  This does not suggest that there is not also value in unit tests that test more of an integration between components (such as a test that will actually invoke services using a the real dispatcher and manipulate entities with the real delegator).
> The goal of this will be to make it easy and very quick to test java-based methods (initial focus on services) along with not having to start an ofbiz container creating a suite of very quick method focused unit tests.
> I have attached a first pass at some of the base classes and a sample of a "mostly complete" unit test for the DateDimensionServices class (which has one method).  Looking for feedback on this approach, potential for community collaboration, and potential buy-in.  Some other things that are still to be done --
> - more samples
> - integration into ant build
> - solution to the "static worker" issue
> - UtilResourceBundle solution (I have it partially commented out)
> - easy verification of service interface adherence (servicedef existance & IN/OUT validation)
> - potential for GenericEntity get/set validation (verify entitydef adherence) (may not want to do this)
> - investigate potential for mocked simple methods
> - ant driven code coverage metrics

--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.

Reply | Threaded
Open this post in threaded view
|

[jira] Commented: (OFBIZ-2842) Add mocked unit test framework

Nicolas Malin (Jira)
In reply to this post by Nicolas Malin (Jira)

    [ https://issues.apache.org/jira/browse/OFBIZ-2842?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12752541#action_12752541 ]

Bob Morley commented on OFBIZ-2842:
-----------------------------------

Hi Phillipp,

This is very interesting; I have not experimented with calling simple methods yet but I am sure it would be possible.  What I mean by the "UtilResourceBundle solution" is this -- when a service attempts to fetch a string from a resource file, if the ofbiz container is not up and running an exception will be thrown.  Because UtilResourceBundle is a utility class of statics, there is no clean way to mock out these method calls.  So my solution was to make a slight modification to the actual UtilResourceBundle so that I could actually programmatically setup "resources" in the context of a unit tester.  This setup is typically just an empty collection so that the service gets the actual resource key passed back and my unit tester can verify that an attempt was made to get that key from a resource file.

In general, I think it is a bad coding practice to make changes to non-tester code for the express purpose of making tests work.  Usually the ability to properly test code is a by-product of a clean design using patterns that promote proper encapsulation and extensibility.  These type of utility classes will always be an issue to "mock" and they are not easily extensible; the way that resources are retrieved is carved in stone.  If I wanted to (for example) retrieve resource values from the database, I have to replace the implementation of the class as opposed to being able to extend the implementation and plug-in this new implementation.  Having said all this, I am not suggesting that every utility class needs to be built in this manner there are plenty of situations where that makes complete sense.

I think your issue with the transaction is another example of this.  The SimpleMethod instance does not provide an ability to use dependency injection on the TransactionUtil class (a static class).  So you paint yourself into a spot where you either have to (potentially) include test code into TransactionUtil or into SimpleMethod.  There is no way to extend the implementation of TransactionUtil to provide additional features or override particular methods and my extension no way to leverage the mocking capabilities to test difficult scenarios.  For example, testing the handling of a timeout exception on the begin method call in exec.  From the unit testers point of view it would be nice to not only know that we attempted to begin a transaction, but we can force an exception and properly verify the handling of that exception.

> Add mocked unit test framework
> ------------------------------
>
>                 Key: OFBIZ-2842
>                 URL: https://issues.apache.org/jira/browse/OFBIZ-2842
>             Project: OFBiz
>          Issue Type: New Feature
>          Components: ALL COMPONENTS
>    Affects Versions: SVN trunk
>            Reporter: Bob Morley
>         Attachments: mockito-all-1.8.0-rc2.jar, OFBIZ-2842.patch
>
>
> Add the ability to create "true" unit tests -- ones that only test the confines of the method itself and using mocking techniques and dependency injection.  This focuses the unit test on the actual code in the method and makes the assumption that other methods have been properly tested and will work.  This does not suggest that there is not also value in unit tests that test more of an integration between components (such as a test that will actually invoke services using a the real dispatcher and manipulate entities with the real delegator).
> The goal of this will be to make it easy and very quick to test java-based methods (initial focus on services) along with not having to start an ofbiz container creating a suite of very quick method focused unit tests.
> I have attached a first pass at some of the base classes and a sample of a "mostly complete" unit test for the DateDimensionServices class (which has one method).  Looking for feedback on this approach, potential for community collaboration, and potential buy-in.  Some other things that are still to be done --
> - more samples
> - integration into ant build
> - solution to the "static worker" issue
> - UtilResourceBundle solution (I have it partially commented out)
> - easy verification of service interface adherence (servicedef existance & IN/OUT validation)
> - potential for GenericEntity get/set validation (verify entitydef adherence) (may not want to do this)
> - investigate potential for mocked simple methods
> - ant driven code coverage metrics

--
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.