2013-07-16 43 views
1
的Mockito我

有一个非常不同的方法调用的,我需要使用JMockit测试框架来测试返回void类型的方法调用。首先让我们看看代码。模拟使用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框架类来连接web服务并获取响应。我的工作是实现这个webservice调用的嘲讽,编写测试用例,以处理实际应用程序中存在的许多类似调用。

这里的问题是 - 如果您的web服务该调用实际上是由该方法port.registerService通过发送姓名,国家和电子邮件作为参数进行。现在我们还将状态和消息变量作为参数传递给此方法。因此,这种方法不是返回状态和消息的某个值,而是在这两个传递参数中的FILLS IN值,这与“RETURN”方法非常不同。

现在的问题是,当我米试图嘲弄使用jmockit这个电话,我可以一直嘲笑这个电话,但什么可以预料的是?因为根本没有回报,结果是一个无效的调用,它填充了传递给它的参数中的值。所以我总是会得到状态,并且如果我嘲笑这个调用,则消息为null,因为我无法在jmockit实现中声明任何返回期望值。

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

+0

可以模拟嘲笑'port.registerService的行为(...)'方法与'result = new Delegate(){void delegate(...){...}};'根据期望记录。这将允许测试指定所需的副作用。但是,如果没有看到测试的完整方法,我不能肯定地说,如果这是你所需要的... –

+0

这里的问题是,实际的方法调用只设置在状态和消息变量变量的值,而无需返回任何东西。 –

+0

是的,但那又如何?我不明白。如果该方法被嘲笑,那么它的实现是什么并不重要。无论如何,你的测试可以完全控制任何模拟方法的行为。 –

回答

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;