Monday, March 12, 2012

Mockito Crib Sheet #2

[Continued...]

5. Capturing arguments passed to a mock:
       String expected = "test string";

toTest.hitTakeArgumentReturnVoid(expected);

ArgumentCaptor stringCaptor = ArgumentCaptor.forClass(String.class);
Mockito.verify(mock).takeArgumentReturnVoid(stringCaptor.capture());
Assert.assertEquals(expected, stringCaptor.getValue());
Note that this capture code can come after the call to the production method.

6. Verifying that a method is never called:
       Mockito.verify(mock, Mockito.never()).takeArguments(Mockito.anyString(), Mockito.anyInt());

Or, equivalently:
      
Mockito.verify(mock, Mockito.times(0)).takeArguments(Mockito.anyString(), Mockito.anyInt());

But I don't like this as the set of methods never called is infinite.

Tuesday, March 6, 2012

Mockito crib sheet

I've been using EasyMock for years. It's very nice but looks somewhat dated when compared to Mockito.

Because I have been using EasyMock for the last 5 years, I'm having trouble kicking the habit. So, here is a list of the more common things I want Mockito to do but keep forgetting how.

1. Using any argument

Use Mockito.anyXXX methods. Here is an example that expects any String:
        Mockito.when(
mock.takeArgument(Mockito.anyString())
).thenReturn(toReturn);
Note that if we mix wildcards with fixed values, we need to use Mockito.eq(...) on the fixed value. For example:
       Mockito.when(mock.takeArguments(Mockito.anyString(), Mockito.eq(2))).thenReturn("returned");


2. Throwing an Exception in a method that does not return anything:
       Mockito.doThrow(x).when(mock).callMethodWhoseReturnTypeIsVoid();

3. The syntax for an expectation looks like:
       Mockito.when(mock.getText()).thenReturn("test")
but for a verification, it looks like:
       Mockito.verify(mock).callMethodWhoseReturnTypeIsVoid();

4. You can decorate collaborating objects and verify they were called. For example:
      ClassToBeMocked real = new ClassToBeMocked();
ClassToBeMocked spy = Mockito.spy(real);
toTest = new ClassForTesting(spy);
toTest.hitMocksVoidMethod();
Mockito.verify(spy).callMethodWhoseReturnTypeIsVoid();
although this is not recommended [1].


[1] Mockito JavaDocs section 13 on "Spying on Real Objects".

Three curious things about Maven

1. The order of goals is significant. Goals clean install do not produce the same result as install clean. For example:

$ mvn clean install > /dev/null
$ ls
pom.xml target
$ mvn install clean > /dev/null
$ ls
pom.xml



2. You might know that you can show the dependency tree with mvn dependency:tree but did you know you can show where in that tree a certain artifact is? This is done by specifying

-Dincludes=[GROUP_ID]:[ARTIFACT_ID][:VERSION]

For example:

$ mvn dependency:tree -Dincludes=:spring-context

selectively shows all the dependencies with the artifact of spring-context.


3. If a library appears multiple times but with different versions, Maven re-orders the dependencies based on how deep in the tree they are. From the Apache documentation:

Dependency mediation - this determines what version of a dependency will be used when multiple versions of an artifact are encountered. Currently, Maven 2.0 only supports using the "nearest definition" which means that it will use the version of the closest dependency to your project in the tree of dependencies. You can always guarantee a version by declaring it explicitly in your project's POM. Note that if two dependency versions are at the same depth in the dependency tree, until Maven 2.0.8 it was not defined which one would win, but since Maven 2.0.9 it's the order in the declaration that counts: the first declaration wins.

"nearest definition" means that the version used will be the closest one to your project in the tree of dependencies, eg. if dependencies for A, B, and C are defined as A -> B -> C -> D 2.0 and A -> E -> D 1.0, then D 1.0 will be used when building A because the path from A to D through E is shorter. You could explicitly add a dependency to D 2.0 in A to force the use of D 2.0