执行单元测试时,Mockito中的MissingMethodInvocationException [英] MissingMethodInvocationException from Mockito when do unit test

查看:4135
本文介绍了执行单元测试时,Mockito中的MissingMethodInvocationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含公共静态方法getProduct(String name)的类:

I have a class which contains an public static method getProduct(String name):

public class ProductManager {
  public static Product getProduct(String name) {
        Product prod = findProduct(name);
        return prod;
  }
}

另一个CustomerService类使用上面的ProductManager:

public class CustomerService {
   ...
   public void handleProduct() {
     Product appleProd = ProductManager.getProduct("apple");
     doHandle(appleProd);
   }
}

我在CustomerService类中的单元测试handleProduct()方法.我使用 mockito 来模拟测试中的ProductManager.getProduct("apple")部分:

I unit test handleProduct() method in CustomerService class. I use mockito to mock the ProductManager.getProduct("apple") part in test:

public class CustomerServiceTest {
  @Test
  public void testHandleProduct() {
    Product mockProd = Mockito.mock(Product.class);

    // MissingMethodInvocationException
    when(ProductManager.getProduct("apple")).thenReturn(mockProd);
    ...
  }
}

但是,当我运行测试时,我从Mockito获得了MissingMethodInvocationException:

However, when I run my test, I got MissingMethodInvocationException from Mockito:

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);

Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
   Those methods *cannot* be stubbed/verified.
   Mocking methods declared on non-public parent classes is not supported.
2. inside when() you don't call method on mock but on some other object.

它抱怨说在when()内部我没有调用方法,但是在when(...)中却调用了 public static 方法ProductManager.getProduct("apple"),为什么Mockito向我提出此错误?我不明白.

It complains that inside when() I don't call method, but I do call the public static method ProductManager.getProduct("apple") in when(...), why Mockito rise this error to me ? I don't understand.

推荐答案

Mockito无法模拟静态方法.将其设为实例方法,您的代码即可使用.

Mockito cannot mock static methods. Make it an instance method and your code will work.

还有其他允许这样做的框架(例如Powermock),但这是相当不好的做法,也是设计不良的标志.您应该创建一个实例并进行依赖项注入.如果某个方法很小,可以在测试其他类(例如Math.max())时进行间接测试,则无需进行模拟.

There are other frameworks that allow that (e.g. Powermock), however this is rather bad practice and a sign of bad design. You should create an instance and do dependency injection. If a method is so small that it can be tested indirectly while testing other class (e.g. Math.max()), than there is no need for mocking.

在您发布的代码中,您有getProduct(),但是在堆栈跟踪中是getArticles()-我假设代码只是一个简化的示例,而堆栈跟踪是实际的.

In the code you posted you have getProduct(), but in the stack trace it is getArticles() - I assume that the code was just a simplified example, while the stack trace is actual.

以下几篇文章解释了测试/模拟静态方法的问题:

Here are a few articles explaining the problem of testing/mocking static methods:

  • https://softwareengineering.stackexchange.com/questions/231594/mocking-static-methods
  • http://misko.hevery.com/2008/12/15/static-methods-are-death-to-testability/
  • http://blog.christianposta.com/testing/java-static-methods-can-be-a-code-smell/
  • Why does Mockito not mock static methods?

这篇关于执行单元测试时,Mockito中的MissingMethodInvocationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆