【问题标题】:Mocking chained method calls in Java/Mockito在 Java/Mockito 中模拟链式方法调用
【发布时间】:2017-07-05 21:25:39
【问题描述】:

我正在使用Mockito 在我当前的项目中模拟服务。 我有一个场景,我需要在代码中模拟链式方法。链式方法使用流畅的设计模式。代码如下。我找不到满足我要求的解决方案。

ProcessCall setValue = ProcessCall.url("").http(HttpMethod.GET).contentType(null).reqHeaders(null).payload(null).create();

我正在尝试像下面那样模拟上面的代码

   @Test
   public void ProcessPost(){
    System.out.println("--------------------------");
    ProcessCall procCall= Mockito.mock(ProcessCall.class, Mockito.RETURNS_DEEP_STUBS);
    Mockito.when(ProcessCall .url("").http(HttpMethod.GET).contentType(null).reqHeaders(null).payload(null).create()).thenReturn(??);   

}

不确定在 thenReturn(??) 方法中传递什么。ProcessCall 是一个具有私有构造函数的类。它有一个 execute() 方法,我需要从调用结果中执行该方法。 我收到以下错误:

  org.mockito.exceptions.misusing.MissingMethodInvocationException: 
  when() requires an argument which has to be 'a method call on a mock'.
  For example:
    when(mock.getArticles()).thenReturn(articles);
 Or 'a static method call on a prepared class`
 For example:
    @PrepareForTest( { StaticService.class }) 
     TestClass{
       public void testMethod(){
          PowerMockito.mockStatic(StaticService.class);
         when(StaticService.say()).thenReturn(expected);
     }
   }

   Also, this error might show up because:
  1. inside when() you don't call method on mock but on some other object.
  2 . inside when() you don't call static method, but class has not been prepared.

谁能帮我解决这个问题。我被这个问题困住了,在 SO 上找不到任何合适的解决方案。

谢谢

【问题讨论】:

  • 以及超越“使用 powermock 进行静态调用”;还可以考虑“不使用静态调用,因此不需要 powermock”。如果您有选择,请在此处选择选项 2;永远!

标签: java unit-testing mockito powermock


【解决方案1】:

我认为该异常最能说明解决方案。当您模拟静态方法时,建议使用 PowerMockito(您需要添加适当的依赖项),然后在测试中:

@RunWith(PowerMockRunner.class)
@PrepareForTest( { ProcessCall.class }) 
public class MyTest{

    @Test
    public void ProcessPost(){
       System.out.println("--------------------------");
       ProcessCall processCallInstance = ProcessCall.getInstance();
       ProcessCall procCall= PowerMockito.mockStatic(ProcessCall.class
                 , Mockito.RETURNS_DEEP_STUBS);
       Mockito.when(ProcessCall .url("").http(HttpMethod.GET)
                   .contentType(null).reqHeaders(null).payload(null).create())
              .thenReturn(processCallInstance);  
       ...
       processCallInstance.execute();
       ...
}

我假设ProcessCall 是一个单例,你需要使用ProcessCall.getInstance(); 之类的东西来获取一个对象,然后将其标记为深度存根调用的结果......然后执行你需要的任何东西。

另外

如果你想模拟 execute() 方法,那么你可以再次使用 PowerMockito 来实现:

@RunWith(PowerMockRunner.class)
@PrepareForTest( { ProcessCall.class }) 
public class MyTest{

    @Test
    public void ProcessPost(){
       System.out.println("--------------------------");
       ProcessCall processCallInstance = PowerMockito.mock(ProcessCall.class);

【讨论】:

  • 谢谢。但不幸的是 power mock 不支持调用静态方法。仍然面临同样的问题,但感谢您的帮助。
  • 尝试使用 PowerMockito.doReturn(processCallInstance).when(ProcessCall) .url("").http(HttpMethod.GET) .contentType(null).reqHeaders(null).payload(null) .create();
猜你喜欢
  • 2015-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多