1

我有一种非常不同的方法调用,我需要使用 JMockit 测试框架对其进行测试。首先让我们看一下代码。

public class MyClass{

   MyPort port;       

   public registerMethod(){
       Holder<String> status=null;
       Holder<String> message=null;

       //below method call is a call to a webservice in the real implementation using apache cxf framework. This method has a void return type. Read below for better explanation.
       port.registerService("name", "country", "email", status, message);

       // do some stuff with status and message here.....

       HashMap response = new HashMap();
       response.put(status);
       response.put(message);

       return response;
   }  

}

现在让我稍微解释一下。这个类基本上有一个端口实例变量,用于连接到 web 服务。webservice 实现使用自动生成的 apache cxf 框架类来连接到 webservice 并获取响应。我的工作是实现这个 web 服务调用的模拟,以便为真实应用程序中存在的许多类似调用编写测试用例。

这里的问题是 - 如果您注意到对 web 服务的调用实际上是由方法 port.registerService 通过发送名称、国家和电子邮件作为参数进行的。现在我们还将状态和消息变量作为参数本身传递给此方法。所以这个方法不是返回一些状态和消息的值,而是在这两个传递的参数中填充值,这与“返回”方法非常不同。

现在的问题是,当我尝试使用 jmockit 模拟这个调用时,我总是可以模拟这个调用,但是会发生什么?因为根本没有返回,所以结果是一个 void 调用,它填充了传递给它的参数中的值。因此,如果我模拟此调用,我将始终获得状态和消息为 null,因为我无法在 jmockit 实现中声明任何返回期望。

如果有人对上述问题有任何解决方案/建议,请回复并尝试帮助我。谢谢。

4

1 回答 1

1

我不确定Holder界面是什么样子,所以我做了一些假设。但是,这是您使用 Mockito 模拟具有 void 返回类型的方法的方式:

@SuppressWarnings("unchecked")
@Test
public final void test() {
    // given
    final String expectedStatus = "status";
    final String expectedMessage = "message";
    final MyPort mockPort = mock(MyPort.class);
    final Answer<Void> registerAnswer = new Answer<Void>() { // actual parameter type doesn't matter because it's a void method
        public Void answer(final InvocationOnMock invocation) throws Throwable {
            // Here I'm stubbing out the behaviour of registerService
            final Object[] arguments = invocation.getArguments();
            // I don't actually care about these, but if you wanted the other parameters, this is how you would get them
            // if you wanted to, you could perform assertions on them
            final String name = (String) arguments[0];
            final String country = (String) arguments[1];
            final String email = (String) arguments[2];

            final Holder<String> statusHolder = (Holder<String>) arguments[3];
            final Holder<String> messageHolder = (Holder<String>) arguments[4];
            statusHolder.put(expectedStatus);
            messageHolder.put(expectedMessage);
            // even though it's a void method, we need to return something
            return null;
        }
    };
    doAnswer(registerAnswer).when(mockPort).registerService(anyString(),
            anyString(), anyString(), any(Holder.class), any(Holder.class));

    final MyClass object = new MyClass();
    object.port = mockPort;

    // when
    final Map<String, String> result = object.registerMethod();

    // then
    assertEquals(expectedStatus, result.get("status"));
    assertEquals(expectedMessage, result.get("message"));
}

作为参考,这些是我的进口:

import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;

import java.util.HashMap;
import java.util.Map;

import org.junit.Test;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
于 2015-11-10T06:00:53.637 回答