Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing doNothing方法不适用于void static方法_Unit Testing_Powermock - Fatal编程技术网

Unit testing doNothing方法不适用于void static方法

Unit testing doNothing方法不适用于void static方法,unit-testing,powermock,Unit Testing,Powermock,我的任务是为一个15年历史的遗留项目添加单元测试代码覆盖率,该项目不使用IoC和0单元测试。我不允许重构代码,因为它在生产环境中工作得非常好,管理层不希望其他团队参与重构,例如QA测试等 服务类有一个performService方法有以下代码 public void performService(requestMessage, responseMessage) { UserAccount userAccount = requestMessage.getUserAccount();

我的任务是为一个15年历史的遗留项目添加单元测试代码覆盖率,该项目不使用IoC和0单元测试。我不允许重构代码,因为它在生产环境中工作得非常好,管理层不希望其他团队参与重构,例如QA测试等

服务类有一个
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);
}
StaticServiceCall.enroll
方法正在调用远程服务。我的单元测试是

@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);
}
当类型stuber中的(T)不适用于参数(void)

如果测试代码更改为

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

您对此有一个误解。你认为你需要说
doNothing()
什么都不做

这是没有必要的!就像这些线一样

@PrepareForTest(StaticServiceCall.class) ... and 
mockStatic(StaticServiceCall.class);
已经足够了

您希望防止在测试期间调用该静态方法时运行该方法的“真实”内容。这就是
mockStatic()
正在做的事情

换句话说:只要使用mockStatic(),真正类的完整实现就会被删除。您只需要使用when/then/doReturn/doThrow,以防发生除nothing以外的事情


意思是:只需删除整个doNothing()行

@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));
}
下面是调用不同服务类的请求消息的基于类的名称的
serviceinpl
代码片段

    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())) {
        ...
虽然测试通过,但由于barebone RequestMessage对象,调用了
EnrollmentService
中的real实现并引发了异常,然后我搜索了其他内容,再次感谢您的澄清