4

I was writing a Junit to test a scenario where an object changes its variables and saves it into the database 2 times. The argumentCaptor is invoked in save operation. The getAllValues() is returning two records. But both values are referenced to the same last capture record.

ImplimentationClass.java

 ...

myObj.setVariable(oneValue);
saveMyObj(myObj);
myObj.setVariable(otherValue);
saveMyObj(myObj);

...

saveMyObj(MyObject myObj){
repository.save(myObj);
}

ImplimentationClassTest.java


private ImplimentationClass underTest ;

@Mock
private Repository mockRepository;

@Before
public void setup(){
  initMocks(this);
  underTest = new ImplimentationClassTest();
}

@Test
public void test(){
ArgumentCaptor<MyObject> captor = ArgumentCaptor.forClass(MyObject.class);
MyObject obj = new MyObject(value);
underTest.implementedMethod(obj);
verify(mockRepository, times(2)).save(captor.capture());
assertEquals(oneValue, captor.getAllValues().get(0).getVariable()); //failing here -getting otherValue
assertEquals(otherValue, captor.getAllValues().get(1).getVariable());

}

Any idea how to capture same object multiple times?

achyutdev
  • 185
  • 2
  • 10
  • I stumble upon the very same problem. I change the same variable during runtime, so that the captor references the same. The debugger shows it well: Although captor.getAllValues() correctly contains 2 objects, both are actually the same instance and thus have the same values etc. I search for a solution within Mockito, but it seems there is none... – BAERUS Sep 02 '22 at 06:37

1 Answers1

1

The problem from your test originates from this piece of code.

myObj.setVariable(oneValue);
saveMyObj(myObj);
myObj.setVariable(otherValue);
saveMyObj(myObj);

Once you change the variable inside of myObj you change it for all references. Note that the ArgumentCaptor does not make a deep copy of myObj. So you will end up with two references to myObj, which only has the latest state.

To avoid this you might want to pass a different instance to the second call.


Another alternative might be to use doAnswer instead and check the correctness of the paramter inside that method.

Check this answer for an example.

second
  • 4,069
  • 2
  • 9
  • 24