[英]Sign up How to test a method invocation inside an anonymous class using mockito
[英]How to test a method invocation inside an anonymous class using mockito
@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");
}
}
}
}
這是我要測試的示例代碼。 我在網上測試匿名 class 時找不到太多東西。 我想通過 newTransactionTemplate.execute 方法測試 exe() 方法 go 並模擬對 reserveService.callReserve(reserveDetails) 的調用。
任何機構都可以建議我如何測試這種情況嗎?
這是我嘗試測試的示例:
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());
}
第二次調用 when(mockTransactionTemplate.execute.. with return object releaseInfo 拋出 java.lang.ClassCastException:
這是上述場景的解決方案。 因為我對測試newTransactionTemplate.execute()的調用不感興趣,所以它是 spring API。 我想測試reserveService.callReserve(reserveDetails)和reserveService.callRelease(id)的調用。 測試這一點的唯一方法是,如果我們創建一個只是通過的事務模板/事務回調“真實”實現/存根。 所以 doIntransaction 方法應該只執行操作。 然后我們可以對操作方法設置期望,在這種情況下是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));
reserveService
是從哪里來的? 如果您通過SomeClass
的構造函數或 setter 注入它,則可以改為傳遞模擬。
// 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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.