执行单元测试时,Mockito中的MissingMethodInvocationException [英] MissingMethodInvocationException from Mockito when do unit test
问题描述
我有一个包含公共静态方法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/
- 为什么Mockito不模拟静态方法?
- 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屋!