2010-11-22 71 views
3

我有一个Mockito问题。用mockito进行单元测试(部分模拟)

是否有可能做这样的事情:

ClassX x = mock(ClassX.class) 
when(x.methodB()).thenReturn("toto"); 
String result = x.methodA(); 

我与1.7的Mockito工作。

我看到有一个“间谍”的系统,但他们说这是不建议在我们测试的项目使用它(为什么?)...

反正我试过,间谍功能,但我得到一个奇怪的行为。

检查什么,我想做的事:

真正的代码:

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")); 
} 

正如他们说我避免了当thenReturn语法,可能是一个问题一个间谍(但它也不管用)

奇怪的是: assertTrue(x.methodB(argument).equals(“good”)); 是好的

只有第二个 assertTrue(x.methodA(argument).equals(“good”)); 也不行

其实helper.methodA(参数)返回“TOTO” - >真正的结果,而不是模拟结果

这是不可能告诉给的Mockito在这种情况下返回“好”? ??看来当测试类调用methodB没关系,但如果间谍调用方法B的方法,它不会工作了...

我不知道该怎么办...是这样一个奇怪的要单元测试同一个类的两个方法,并使测试彼此独立,这样一个着名的模拟测试框架不会实现这个基本功能?这不就是我们所说的真正的单元测试吗?不明白为什么他们说要避免使用间谍方法的测试对象...

感谢

+0

刚刚用Mockito 1.9.5试了一下,两个都返回了''好的'''。所以我想这种行为已经消失了。 – acdcjunior 2013-08-13 18:50:44

回答

2

间谍在暗中监视对象不同的对象。间谍只委托侦察对象。所以当侦察对象从methodA调用methodB时,它会自己调用它,而不是间谍。

+0

谢谢:)但你有解决方案来做我想要的? – 2010-11-22 14:24:22

+0

我想我可以使用一个匿名的真正的类并重写MethodB,但mockito并没有给出适当的解决方案? – 2010-11-22 14:25:18

+0

而是将'methodB'放在另一个对象上,该对象作为具有'methodA'的对象的依赖项,例如作为构造器参数。这样你可以模拟'methodB'对象。如果你给你的对象和方法的专有名称,我可以为你建议更好的名字。 – 2010-11-22 14:31:16

4

更新: 我写了下面的东西,然后片刻后发现.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); 
    } 

} 
相关问题