We have a class whose purpose is to change the values in some fields of a received object and keep the values of its other fields
public void process(SomeType someObject) {
SomeType modifiedObject = modifyObject(someObject);
nextClass.process(modifiedObject);
}
private SomeType modifyObject(SomeType someObject) {
String someValueFromServiceCall = someService.getSomeValue(...);
SomeType modifiedObject = new SomeType.Builder()
.withSomeFieldValuesFromSomeObjectItself(...)
.withSomeFieldValuesFromServiceCall(someValueFromServiceCall)
.build();
return modifiedObject;
}
SomeType
is a legacy class which we can create using only its builder class and it has no setter methods. This means we cannot modify the received someObject
itself, but have to build and return a new SomeType
object from modifyObject()
, which the main method then can pass on for processing to the next class
However this seems to raise problems during unit testing. We don't seem to be able to access the internal modifiedObject
from the unit test class and such as we don't seem to be able to do expects/asserts on it
SomeType someObject = createSomeObjectForTest();
expect(someServiceMock.getSomeValue(...)).andReturn(SOME_VALUE);
expect(nextClassMock.process(someObject)).andReturn(...); //this is not someObject, but the new internal modifiedObject created within underTest
underTest.process(someObject);
assertEquals(someObject.getSomeField(), SOME_VALUE); //this is not someObject, but the new internal modifiedObject created within underTest
Here's how to use the ArgumentCaptor
:
// mock and make sure all fields required for modify are set
SomeType arg = create();
ArgumentCaptor<SomeType> captor = ArgumentCaptor. forClass(SomeType.class);
sut.process(arg) ;
verify (nextClass). process(captor.capture());
SomeType modified = captor.get();