Java 使用mockito进行单元测试(部分模拟)
我对莫基托有意见 有没有可能做这样一件事:Java 使用mockito进行单元测试(部分模拟),java,unit-testing,mocking,mockito,partial-mocks,Java,Unit Testing,Mocking,Mockito,Partial Mocks,我对莫基托有意见 有没有可能做这样一件事: ClassX x = mock(ClassX.class) when(x.methodB()).thenReturn("toto"); String result = x.methodA(); 我在用Mockito 1.7 我看到有一个“间谍”系统,但他们说不建议在我们测试的项目上使用它(为什么?) 不管怎样,我试过那个间谍功能,但我有一种奇怪的行为 检查我想做什么: 实数代码: String methodA(String arg) { re
ClassX x = mock(ClassX.class)
when(x.methodB()).thenReturn("toto");
String result = x.methodA();
我在用Mockito 1.7
我看到有一个“间谍”系统,但他们说不建议在我们测试的项目上使用它(为什么?)
不管怎样,我试过那个间谍功能,但我有一种奇怪的行为
检查我想做什么:
实数代码:
String methodA(String arg) {
return this.methodB(arg);
}
String methodB(String arg) {
return "toto";
}
测试代码:
@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") );
}
正如他们所说,我避免了when-thenReturn语法,这可能是间谍的问题(但无论如何它也不起作用)
奇怪的是:
assertTrue(x.methodB(参数).equals(“good”);
没关系
只有第二个
assertTrue(x.methodA(参数).equals(“good”);
不好
实际上,helper.methodA(参数)返回“toto”->实际结果,而不是模拟结果
在这种情况下,不可能让mockito返回“good”???当测试类调用methodB时,它似乎没有问题,但是如果间谍的方法调用methodB,它就不再工作了
我不知道该怎么办。。。对同一类的两个方法进行单元测试并使测试相互独立,以至于一个著名的模拟测试框架无法实现这个基本功能,这是不是很奇怪?这不是我们所说的真正的单元测试吗?我不明白为什么他们说要避免在测试对象上使用间谍方法
谢谢间谍与被间谍不同。间谍只委派给被间谍的对象。因此,当spied对象从methodA调用methodB时,它将在自身而不是spy上调用它。更新: 我写了下面的内容,不久之后发现了.thenCallRealMethod(),它允许您有效地执行部分存根。Mockito的作者建议您使用重构将依赖项分离到不同的类中;但它们确实提供了部分存根的方法。我添加了一个测试方法来演示这种方法,并留下了我的原始评论 原件: 我真的很喜欢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);
}
}
谢谢:)但是你有一个解决方案来做我想做的吗?我想我可以使用一个匿名的实类并重写MethodB,但是mockito没有给出一个合适的解决方案?而是将
MethodB
放在另一个对象上,这个对象作为具有methodA
的对象的依赖项,例如作为构造函数参数。这样就可以模拟methodB
对象。如果你给出你的对象和方法的专有名称,我可以为你推荐更好的名称。谢谢。因此,似乎没有办法使用spy并将这两个方法放在同一个类中。。。SAD应该仅仅为了模拟和测试而将methodB
移出,即使(1)methodA和methodB
完全属于同一类,并且(2)methodB
是methodA
使用的一段常见代码?只需在Mockito 1.9.5中尝试了这一点,并且都返回了“good”
。所以我想这种行为已经消失了。