Reputation: 419
I have a problem understanding what is going on in the Mockito framework here. I have the following classes
Model class
public class KeyValueImpl{
private String key;
private String value;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
"business logic" class
public class ValueFinder {
public KeyValueImpl findValueForKey(KeyValueImpl keyValue){
keyValue.setValue("foo");
return keyValue;
}
}
Utility class to return the expected result (will be mocked)
public class ExpectationManager {
public String getExpectedValue(){
return "loremipsumdolorem";
}
}
Test class
public class ValueFinderTest {
@Test
public void testMocked() {
KeyValueImpl keyValue = Mockito.mock(KeyValueImpl.class);
keyValue = (new ValueFinder()).findValueForKey(keyValue);
ExpectationManager expectationManager = Mockito.mock(ExpectationManager.class);
when(expectationManager.getExpectedValue()).thenReturn("somethingDifferentToFoo");
String expectedValue = expectationManager.getExpectedValue();
verify(keyValue).setValue(expectedValue); //fails, expects "foo" but gets "somethingDifferentToFoo" -> ok
verify(keyValue).setValue(expectationManager.getExpectedValue()); //no error, but why?
}
}
The interesting thing happens in the last row of the test class:
verify(keyValue).setValue(expectationManager.getExpectedValue()); //no error, but why?
I would certainly expect the same behaviour like in the row above
verify(keyValue).setValue(expectedValue); //fails, expects "foo" but gets somethingDifferentToFoo" -> ok
However Mockito let's me get along with it. Any explantation for this?
Upvotes: 0
Views: 678
Reputation: 1500055
I suspect the problem is due to the order of the calls. Your last line is effectively:
KeyValueImpl tmp = verify(keyValue);
String value = expectationManager.getExpectedValue();
tmp.setValue(value);
If Mockito is effectively using the verify
method call as a marker to say "the next time a mocked method gets called, check it" without validating which mock it's called on, then it'll be the expectationManager.getExpectedValue()
call that is verified.
While I would argue this is confusing behaviour in Mockito, I'd also argue that it's a confusing test - using one mock within the verification step of another feels like a design smell to me. I'd strongly consider using manually-written fakes rather than mocks where possible, simply to avoid too much interaction between mocks.
Upvotes: 1