2010-11-22 72 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); 
    } 

} 
相關問題