The Mockito library is the most popular Java unit test helper in these days. But even with popular frameworks you sometimes encounter surprising effects. This Blog is about a debugging session that ended in a big Hello when reading the JavaDoc of Mockito.anyString()
, which serves for simulating parameters in mock method calls. Anyone that doubts the usefulness of JavaDoc should read along, together with the Mockito addicts.
For more Mockito gotchas you may also want to read this article about @InjectMocks
. We are walking on thin ice.
I want to test a name-converter. My NameConverter
class provides a convertName(String name)
method which I want to call to assert that it works without exception.
Aim is to show the effect of Mockito.anyString()
, and all other available anyXXX()
methods, when passing either a non-null or a null value to an actual mock-instance. Reason is that their behaviour changed since version 2.1.0, which may break also your tests.
1 | import static org.junit.Assert.*; |
I statically import all static methods from Assert
and Mockito
on line 1 and 2, so that I can write when(....)
instead of Mockito.when(....)
.
On line 8 the unit test class starts. On line 10 there is the tested class NameConverter
, implemented as inner class. I allocate an instance through the @Mock
annotation upon field nameConverter
on line 18, and the @Before
method initMocks()
on line 23, where the NameConverter
mock instance gets created by Mockito through initMocks(this)
on line 24.
On line 25 I teach the mock how to behave, I tell it that it always should return "Sloppy"
when convertName()
gets called. For this 'stubbing' (=teaching) I use anyString()
to express that the actual parameter value should not not determine the return in any way. Mind that the method call convertName(anyString())
goes to a mock object, and thus is not a call to a real NameConverter
object, it just should look like. They call this "intuitive reading".
So far the test class initialization. The actual tests are the methods below, annotated by @Test
. And here the gotcha starts, because the return is not always "Sloppy"
when I call the convertName
method!
The testNonNullParameter()
is successful as expected.
But testNullParameter()
is not. It fails when you use a Mockito above 2.1.0. Message is
expected:<Sloppy> but was <null>
Null
is what Mockito returns from a call that learnt no behaviour.
Read the comment on line 42 (extracted from JavaDoc) to understand the new behaviour of anyString()
.
testNullParameter()
test fails because a call with a null parameter does not match the behavior learnt in when()
. And what behavior means is determined by the library, not by you. The correct name for anyXXX()
would be anyXXXExceptNull()
now.ɔ⃝ Fritz Ritzberger, 2020-03-23