@Transactional(propagation = Propagation.REQUIRED)
public void exe() {
try {
Reserve reserveInfo = newTransactionTemplate.execute(new TransactionCallback<Reserve>() {
@Override
public Reserve doInTransaction(TransactionStatus status) {
return reserveService.callReserve(reserveDetails);
}
});
if(reserveInfo != null && reserveInfo.getStatus()=="DONE") {
someOtherService.doSomething();
}
} finally {
if(reserveInfo!= null && reserveInfo.getStatus().equals("DONE")){
final String id = reserveInfo.getId();
Release releaseInfo = newTransactionTemplate.execute(new TransactionCallback<Release>() {
@Override
public Release doInTransaction(TransactionStatus status) {
return reserveService.callRelease(id);
}
});
if (releaseInfo.getStatus() != "RELEASED") {
throw new RuntimeException("Problem in releaseing");
}
}
}
}
This is the sample code I want to test. I couldn't find much on testing anonymous class on net. I want to test the exe() method, go through newTransactionTemplate.execute method and mock the call to reserveService.callReserve(reserveDetails).
Can any body please suggest how can I test this situation?
here is the sample how i'm trying to test:
private SomeService someService = null;
@Mock
private ReserveService mockReserveService;
@Mock
private ReleaseService mockReleaseService;
@Mock
private TransactionTemplate mockTransactionTemplate;
@Mock
private SomeOtherService mockSomeOtherService;
@BeforeMethod
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
someService = new SomeService();
someService.setReserveService(mockReserveService);
someService.setReleaseService(mockReleaseService);
someService.setSomeOtherService(mockSomeOtherService);
someService.setNewTransactionTemplate(mockTransactionTemplate);
}
@Test(enabled=true)
public void exeHappyPath() {
Reserve reserveInfo = new Reserve();
reserveInfo.setId("123");
reserveInfo.setStatus("DONE");
Release releaseInfo = new Release();
releaseInfo.setStatus("RELEASED");
when(mockReserveService.callReserve(Mockito.any(ReserveDetails.class))).thenReturn(reserveInfo);
when(mockReserveService.callRelease(reserveInfo.getId())).thenReturn(releaseInfo);
when(mockTransactionTemplate.execute(Mockito.<TransactionCallback<Reserve>>any())).thenReturn(reserveInfo);
when(mockTransactionTemplate.execute(Mockito.<TransactionCallback<ReleaseInfo>>any())).thenReturn(releaseInfo);
//Call the exe method
someService.exe();
verify(mockReserveService, times(1)).callReserve(Mockito.any(ReserveDetails.class));
verify(mockReserveService, times(1)).callRelease(reserveInfo.getId()));
verify(mockSomeOtherService, times(1)).doSomthing());
}
The second call to when(mockTransactionTemplate.execute.. with return object releaseInfo throws java.lang.ClassCastException:
If you feel the need to test the behavior of your anonymous class move it outside of the publishRequest method, make it either a top level class or a static class in the class containing your publishRequest method.
For Mockito, there is no direct support to mock private and static methods. In order to test private methods, you will need to refactor the code to change the access to protected (or package) and you will have to avoid static/final methods.
Where does reserveService
come from? If you are injecting it through either SomeClass
's constructor or a setter, you can pass a mock instead.
// Set up your mock and stub out the method call
ReserveService reserveService = mock(ReserveService.class);
when(reserveService.callReserve(any(ReserveDetails.class))).thenReturn(null);
// Inject, either via constructor or setter
SomeClass instance = new SomeClass(reserveService);
// Or, instance.setReserveService(reserveService);
Here is the solution to the above mentioned scenario. As I was not interested in testing the invocation of newTransactionTemplate.execute(), it being an spring API. I wanted to test the invocation of reserveService.callReserve(reserveDetails) and reserveService.callRelease(id). The only way to test this is if we create a transactiontemplate/transactioncallback "real" implementation/stub that is just pass thru. so the doIntransaction method should do nothing more than execute the action. then we can set expectation on the action methods which in this case is the reserveService.
when(mockTransactionTemplate.execute(Mockito.<TransactionCallback>any())).thenAnswer(new Answer() {
public Object answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
TransactionCallback arg = (TransactionCallback)args[0];
return arg.doInTransaction(new SimpleTransactionStatus());
}
});
when(mockResourceService.callReserve(any(ReserveDetails.class))).thenReturn(reserveInfo);
when(mockResourceService.callRelease(eq(id))).thenReturn(releaseInfo);
//Call the exe method
someService.exe();
verify(mockResourceService, times(1)).callReserve(any(ReserveDetails.class));
verify(mockSomeOtherService, times(1)).doSomthing());
verify(mockMemberResourceService, times(1)).callRelease(eq(id));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With