java 使用 mockito 进行单元测试(部分模拟)
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4246088/
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
Unit-testing with mockito (partial mocking)
提问by Sebastien Lorber
I have a problem with Mockito.
我有 Mockito 的问题。
Is it possible to do such a thing:
是否有可能做这样的事情:
ClassX x = mock(ClassX.class)
when(x.methodB()).thenReturn("toto");
String result = x.methodA();
I'm working with Mockito 1.7.
我正在使用 Mockito 1.7。
I saw there was a "spy" system but they say it's not recommended to use it (why?) on the item we test...
我看到有一个“间谍”系统,但他们说不建议在我们测试的项目上使用它(为什么?)...
I tried that spy function anyway but i get a strange behaviour.
无论如何,我尝试了该间谍功能,但出现了奇怪的行为。
Check what i want to do:
检查我想做什么:
Real code:
真实代码:
String methodA(String arg) {
return this.methodB(arg);
}
String methodB(String arg) {
return "toto";
}
Test code:
测试代码:
@Test
public void testTest() {
final ClassX x = spy( new ClassX() );
final String argument = "arg";
doReturn("good").when(helper).methodB(argument);
assertTrue( x.methodB(argument).equals("good") );
assertTrue( x.methodA(argument).equals("good") );
}
As they said i avoided the when thenReturn syntax that could be a problem with a spy (but it doesn't work either anyway)
正如他们所说,我避免了 when thenReturn 语法可能是间谍的问题(但无论如何它也不起作用)
The strange thing is that: assertTrue( x.methodB(argument).equals("good") ); is OK
奇怪的是: assertTrue( x.methodB(argument).equals("good") ); 没问题
Only the second assertTrue( x.methodA(argument).equals("good") ); is not OK
只有第二个 assertTrue( x.methodA(argument).equals("good") ); 不行
Actually helper.methodA(argument) returns "toto" -> the real result and not the mock result
实际上 helper.methodA(argument) 返回“toto”-> 真实结果而不是模拟结果
It isn't possible to tell mockito to return "good" in this case??? It seems when the test class call methodB it's ok, but if a method of the spy calls the methodB it doesn't work anymore...
在这种情况下,不可能告诉 mockito 返回“好”???看起来当测试类调用methodB时还可以,但是如果间谍的一个方法调用methodB它就不再起作用了......
I don't know what to do... is it such a strange thing to unit-test 2 methods of the same class and make the tests independent from each others so that a famous mock-test framework doesn't implement this basic function? Isn't it what we just call real unit-testing? Don't understand why they say to avoid using spy method on the tested object...
我不知道该怎么办......对同一类的2个方法进行单元测试并使测试相互独立,这样一个著名的模拟测试框架就没有实现这个基本功能,这是一件很奇怪的事情吗? ? 这不就是我们所说的真正的单元测试吗?不明白为什么他们说要避免在测试对象上使用 spy 方法......
Thanks
谢谢
采纳答案by Christoffer Hammarstr?m
The spy is a different object from the spied object. The spy only delegates to the spied object. So when the spied object calls methodB from methodA, it will call it on itself, not on the spy.
间谍与被监视的对象是不同的对象。间谍只委托给被监视的对象。所以当被监视的对象从 methodA 调用 methodB 时,它会在自身上调用它,而不是在 spy 上调用。
回答by Fred Haslam
UPDATE: I wrote the stuff below, and then moments later discovered .thenCallRealMethod() which allows you to effectively perform partially stubbing. Mockito authors recommend you use refactoring to separate dependencies into different classes; but they do provide the means to partially stub. I have added a test method to demonstrate this approach, and leave my original comments.
更新:我写了下面的东西,然后过了一会儿发现 .thenCallRealMethod() 它允许你有效地执行部分存根。Mockito 作者建议您使用重构将依赖项分离到不同的类中;但它们确实提供了部分存根的方法。我添加了一个测试方法来演示这种方法,并留下我的原始评论。
ORIGINAL: I really like Mockito, but this is the one place where EasyMock wins out. I have two solutions for you that don't involve Mockito. The first is to override methodB on your testing instance. The other is to partially mock with EasyMock:
原文:我真的很喜欢 Mockito,但这是 EasyMock 胜出的地方。我有两个不涉及 Mockito 的解决方案。第一个是在您的测试实例上覆盖 methodB。另一种是用 EasyMock 部分模拟:
import org.junit.Test;
import static org.junit.Assert.*;
import static org.easymock.EasyMock.*;
public class PartialMockTest {
class ClassX {
String methodA(String arg) {return methodB(arg);}
String methodB(String arg) {return "toto";}
}
@Test
public void MockitoOnClassX(){
ClassX classx = mock(ClassX.class);
when(classx.methodB("hiyas")).thenReturn("tomtom");
when(classx.methodA(anyString())).thenCallRealMethod();
String response = classx.methodA("hiyas");
assertEquals("tomtom",response);
}
@Test
public void OverrideOnClassX() {
ClassX classx = new ClassX(){@Override String methodB(String arg){return "tomtom";}};
String response = classx.methodA("hiyas");
assertEquals("tomtom",response);
}
@Test
public void PartialMockOnClassX() throws NoSuchMethodException {
ClassX classx = createMockBuilder(ClassX.class).addMockedMethod("methodB").createMock();
expect(classx.methodA("hiyas")).andReturn("tomtom");
replay(classx);
String response = classx.methodA("hiyas");
assertEquals("tomtom",response);
}
}