在进行单元测试时,Mockito发生MissingMethodInvocationException

时间:2015-11-09 10:09:13

标签: java unit-testing junit mockito

我有一个包含公共静态方法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);
   }
}

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

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

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

然而,当我进行测试时,我从Mockito获得MissingMethodInvocationException

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()内部没有调用方法,但是我在ProductManager.getProduct("apple")中调用了公共静态方法when(...),为什么Mockito会提升这个对我有误?我不明白。

1 个答案:

答案 0 :(得分:1)

Mockito无法模拟静态方法。使它成为一个实例方法,您的代码将起作用。

还有其他框架可以允许(例如Powermock),但这是一种相当糟糕的做法,也是设计糟糕的表现。您应该创建一个实例并执行依赖注入。如果一个方法非常小,可以在测试其他类时间接测试(例如Math.max()),那么就不需要进行模拟。

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

以下是一些解释测试/模拟静态方法问题的文章: