2017-07-31 67 views
1

我被分配爲將單元測試代碼覆蓋率添加到未使用IoC和0單元測試的15年舊傳統項目。我不允許重構代碼,因爲它適用於生產精細完美,管理層不希望其他球隊參與的重構如QA測試等doNothing方法不適用於無效靜態方法

服務類有一個performService方法如下代碼

public void performService(requestMessage, responseMessage) { 
     UserAccount userAccount = requestMessage.getUserAccount(); 
     GroupAccount groupAccount = requestMessage.getGroupAccount(); 
     Type type = requestMessage.getType(); 
     StaticServiceCall.enroll(userAccount, groupAccount, type); 
     response.setStatus(Status.SUCCESS); 
} 

This StaticServiceCall.enroll method is calling remote services。我的單元測試是

@RunWith(PowerMockRunner.class) 
@PrepareForTest(StaticServiceCall.class) 
public class EnrollmentServiceTest { 

@Test 
public void testPerformService() {  
    mockStatic(StaticServiceCall.class); 
    doNothing().when(StaticServiceCall.enroll(any(UserAccount.class), any(GroupAccount.class), any(Type.class))); 
    service.performService(requestMessage, responseMessage); 
    assertEquals("Enrollment should be success, but not", Status.SUCCESS, response.getStatus); 
} 

的Eclipse與The method when(T) in the type Stubber is not applicable for the arguments (void)

的Eclipse停止抱怨抱怨,如果測試代碼改變

mockStatic(StaticServiceCall.class); 
doNothing().when(StaticServiceCall.class); 
StaticServiceCall.enroll(any(UserAccount.class), any(GroupAccount.class), any(Type.class)); 
service.performService(requestMessage, responseMessage); 
assertEquals("Enrollment should be success, but not", Status.SUCCESS, response.getStatus); 

測試用例UnfinishedStubbingException失敗。我正在使用powermock 1.6.6

回答

2

您的結局存在一個誤解。你認爲你需要說doNothing()應該什麼都不做

這沒有必要!由於這些行

@PrepareForTest(StaticServiceCall.class) ... and 
mockStatic(StaticServiceCall.class); 

已經足夠。

您希望在測試期間調用該方法時防止該靜態方法的「真實」內容運行。這就是mockStatic()正在做的事情。

換句話說:只要你使用mockStatic()的完整實現真正的類是擦拭。你只需要使用when/then/doReturn/doThrow以防萬一你想發生什麼elsenothing

含義:只刪除整個doNothing()行!

1

@GhostCat - 謝謝你的回答,它解決的問題,我的誤解,從這個測試用例

@Test 
public void testEnrollmentServiceSuccess() { 
    RequestMessage requestMessage = new RequestMessage(); 
    requestMessage.setName("ENROLL"); 
    ResponseMessage responseMessage = new ResponseMessage(); 

    EnrollmentService mockService = mock(EnrollmentService.class); 
    mockService.performService(any(RequestMessage.class), any(ResponseMessage.class)); 

    mockStatic(ClientManager.class); 
    when(ClientManager.isAuthenticated()).thenReturn(true); 

    ServiceImpl service = new ServiceImpl(); 
    service.performService(requestMessage, responseMessage); 
    verify(mockService).performService(any(RequestMessage.class), any(ResponseMessage.class)); 
} 

這裏來,是請求消息的ServiceImpl類基於名稱的代碼片段調用不同的服務類

public void performService(RequestMessage request, ResponseMessage response) { 
    try { 
     if (request == null) { 
      throw new InvalidRequestFormatException("null message"); 
     } 
     if (!ClientManager.isAuthenticated()) { 
      throw new ServiceFailureException("not authenticated"); 
     } 
     // main switch for known services 
     if ("ENROLL".equals(request.getName())) { 
      service = new EnrollmentService(); 
      service.performService(request, response); 
     } else if ("VALIDATE".equals(request.getName())) { 
     ... 

雖然測試通過,在EnrollmentService真正實施得到了又一次打來電話,由於拋向準系統RequestMessage對象異常,然後我用Google搜索了doNothing,感謝您的clarifica