java 计算间接方法调用 Mockito
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7829659/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Count indirect method calls Mockito
提问by catdog
I'm having problems with counting method calls with Mockito. Problem is that the method whos calls I want to count is called in test class indirectly by other method. Here is the code:
我在使用 Mockito 计算方法调用时遇到问题。问题是我想计数的方法在测试类中被其他方法间接调用。这是代码:
public class ClassForTest {
private Integer value;
public void doSmth() {
prepareValue("First call");
prepareValue("Second call");
prepareValue("Third call");
System.out.println(value);
}
protected void prepareValue(String msg) {
System.out.println("This is message: " + msg);
value++;
}
}
And the test class:
和测试类:
public class ClassForTestTest extends TestCase {
@Test
public void testDoSmth() {
ClassForTest testMock = mock(ClassForTest.class);
doNothing().when(testMock).prepareValue(anyString());
testMock.doSmth();
verify(testMock, times(3)).prepareValue(anyString());
}
}
Having such exception:
有这样的例外:
Wanted but not invoked:
classForTest.prepareValue(<any>);
-> at org.testing.ClassForTestTest.testDoSmth(ClassForTestTest.java:24)
However, there were other interactions with this mock:
-> at org.testing.ClassForTestTest.testDoSmth(ClassForTestTest.java:21)
Any ideas please. Thanks in advance!
请有任何想法。提前致谢!
回答by Garrett Hall
This will work. Using a spy
calls the underlying method. Make sure value
is initialized first.
这将起作用。使用 aspy
调用底层方法。确保value
首先初始化。
@Test
public void testDoSmth() {
ClassForTest testMock = spy(new ClassForTest());
testMock.doSmth();
verify(testMock, times(3)).prepareValue(anyString());
}
public class ClassForTest {
private Integer value = 0;
public void doSmth() {
prepareValue("First call");
prepareValue("Second call");
prepareValue("Third call");
System.out.println(value);
}
protected void prepareValue(String msg) {
System.out.println("This is message: " + msg);
value++;
}
}
回答by Ryan Stewart
This is an indication that you need some refactoring to improve your design. A single class should be fully testable without needing to mock out pieces of it. Whatever pieces you feel need to be mocked out should be extracted into one or more collaborating objects. Don'tfall into the trap of partial mocks. Listen to what the tests are telling you. Your future self will thank you.
这表明您需要进行一些重构来改进您的设计。单个类应该是完全可测试的,而无需模拟它的各个部分。您认为需要模拟的任何部分都应提取到一个或多个协作对象中。不要落入部分模拟的陷阱。听听测试告诉你什么。你未来的自己会感谢你。
回答by Garrett Hall
Alternatively, if you want to refactor for testability, you can do the following:
或者,如果您想重构以提高可测试性,您可以执行以下操作:
@Test
public void testDoSmth() {
Preparer preparer = mock(Preparer.class);
ClassForTest cft = new ClassForTest(preparer);
cft.doSmth();
verify(preparer, times(3)).prepareValue(anyString());
}
public class ClassForTest {
private final Preparer preparer;
public ClassForTest(Preparer preparer) {
this.preparer = preparer;
}
public void doSmth() {
preparer.prepareValue("First call");
preparer.prepareValue("Second call");
preparer.prepareValue("Third call");
System.out.println(preparer.getValue());
}
}
public class Preparer {
private Integer value = 0;
public void prepareValue(String msg) {
System.out.println("This is message: " + msg);
value++;
}
public Integer getValue() {
return value;
}
}
回答by Bringer128
You are mocking the tested class. Mocking is intended for the dependencies of a tested class, rather than the class itself.
您正在嘲笑经过测试的课程。模拟用于测试类的依赖项,而不是类本身。
I suspect what you want is Mockito.spy()
. However, this is partial mockingwhich the Mockito Javadoc recommends against.
我怀疑你想要的是Mockito.spy()
. 然而,这是Mockito Javadoc 建议反对的部分模拟。