I am facing the below problem where, when indirectly updating the fields on a spy object, the spy does NOT see updates on primitive fields, whereas it sees on reference once.
As an example:
import org.junit.Test;
import org.mockito.Mockito;
import java.util.function.Consumer;
import java.util.concurrent.atomic.AtomicBoolean;
public class MyTest {
class Actor {
Consumer<Boolean> consumer;
void init(Consumer<Boolean> consumer){
this.consumer = consumer;
}
void act(boolean flag){
this.consumer.apply(flag);
}
}
class TestClass {
boolean field = true;
AtomicBoolean refField = new AtomicBoolean(true);
TestClass(Actor actor){
actor.init( flag -> {
System.out.println("Changing field to " + flag);
field = flag;
refField.set(flag);
});
}
void call(){
this.doSomething(field);
}
void callRef(){
this.doSomething(refField.get());
}
void doSomething(boolean flag){
System.out.println("#doSomething(" + flag + ")");
}
}
@Test
public void test(){
// given an actor and a spied TestClass
Actor actor = new Actor();
TestClass spy = Mockito.spy(new TestClass(actor));
// when invoking the action with the primitive
spy.call();
// then expect correct invocation
Mockito.verify(spy, Mockito.times(1)).doSomething( true );
// when invoking the action with the ref field
spy.callRef();
// then expect correct invocation
Mockito.verify(spy, Mockito.times(2)).doSomething( true );
// when changing the flag to 'false'
actor.act( false );
// and invoking the action with the refField
spy.callRef();
// then expect correct invocation
Mockito.verify(spy, Mockito.times(1)).doSomething(false);
// when invoking the action with the primitive
spy.call();
// then method is NOT invoked as expected !!!!!!!
Mockito.verify(spy, Mockito.times(2)).doSomething(false);
}
}
The last verification, will fail, as the method is called with the first primitive value.
I was wondering why this is happenning? Is this an expected behaviour. Running the above test, will produce the below logging:
#doSomething(true)
#doSomething(true)
Changing flag to false
#doSomething(false)
#doSomething(true)
I would expect the last log statement to be invoked with false
.
Any insights on the above?
PS: Version=mockito-core:2.25.0