Suppose we have the following Java interface (and we are only using interfaces because we want to demonstrate using Groovy to test Java using Mocks later):
Now suppose we have an implementation method as follows:
For numbers, the
reverse() method will negate them. Thanks to duck-typing, other objects that we try to reverse will just call their respective types
reverse() method if it exists, e.g. so it will work for
Now suppose we make use of a reverser in some code we are trying to test.
We can integration test this class as follows:
The above tests our class under test with the production reverser in place. For this particular example, we might argue that such a test is appropriate and sufficient. However, in more complicated scenarions, the dependent collaboration class (
GroovyReverser in this case) might be difficult or expensive to construct. In those cases, we would want to replace it with a mock or stub. See Groovy Mocks for a definition of terms.
Using Groovy's Built-in Mocking capabilities
Here is how we would use Groovy's built-in mock support to test our class under test in isolation:
Note that we didn't need to do anything to inject our mocks into the class under test. Inside the
use method, all attempts to create a
GroovyReverser object will be replaced by a mock object. This also works for Java objects created by Groovy objects, as the following shows:
JavaReverser is a class that we have defined as follows:
Hmmm. Quite a bit longer than the Groovy version. Bit we digress.
Now, consider now the following Java class:
We now want to test this too and we want to use Groovy to write the tests. Unfortunately, Groovy's built-in mock support won't help us here. It doesn't allow us to test Java classes like this one as it relies on hooking into Groovy's object lifecycle mechanisms. Instead, we can use any of the available Java mocking packages as shown in the examples that follow.
EasyMock provides Mock Objects for interfaces in tests by generating them on the fly using Java's proxy mechanism. That's just what we need here. Several versions are available. We are using version 2.2 which relies on Java 5. Here is how we can test our class using that version of EasyMock:
Here is how we can test the class using RMock:
Here is how we can test the class using JMock:
JDummy is a thin API which sits above JMock. It allows very succinct expectation setting code when the expectation code would normally involve many stubs. Our example is so simple, that its power is not illustrated.
Here is how we can test the class using JDummy: