2017-07-31 122 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