2015-06-11 65 views
29

例如,我有處理程序:如何模擬@InjectMocks類的方法?

@Component 
public class MyHandler { 

    @AutoWired 
    private MyDependency myDependency; 

    public int someMethod() { 
    ... 
    return anotherMethod(); 
    } 

    public int anotherMethod() {...} 
} 

,以測試它,我想寫的東西是這樣的:

@RunWith(MockitoJUnitRunner.class} 
class MyHandlerTest { 

    @InjectMocks 
    private MyHandler myHandler; 

    @Mock 
    private MyDependency myDependency; 

    @Test 
    public void testSomeMethod() { 
    when(myHandler.anotherMethod()).thenReturn(1); 
    assertEquals(myHandler.someMethod() == 1); 
    } 
} 

但它實際上調用anotherMethod()每當我試圖嘲笑它。我應該怎麼處理myHandler來嘲笑它的方法?

+0

如果你想測試MyHandler的,你不應該嘲笑它自己的方法(因爲你想測試你的處理程序,而不是模擬)。是否有一個特定的原因,你需要這樣做? – Nitek

回答

55

第一所有嘲笑MyHandler方法的原因可能如下:我們已經測試了anotherMethod()並且它有複雜的邏輯,那麼爲什麼我們需要再次測試它(如someMethod()的一部分),如果我們只能調用verify
我們可以做到這一點通過:

@RunWith(MockitoJUnitRunner.class} 
class MyHandlerTest { 

    @Spy 
    @InjectMocks 
    private MyHandler myHandler; 

    @Mock 
    private MyDependency myDependency; 

    @Test 
    public void testSomeMethod() { 
    doReturn(1).when(myHandler).anotherMethod(); 
    assertEquals(myHandler.someMethod() == 1); 
    verify(myHandler, times(1)).anotherMethod(); 
    } 
} 

注:「間諜」對象的情況下,我們需要使用doReturn代替thenReturn(小的解釋是here

0

在你的代碼中,你根本沒有測試MyHandler。你不想嘲笑你正在測試的東西,你想調用它的實際方法。如果MyHandler具有依賴關係,您可以嘲笑它們。

事情是這樣的:

public interface MyDependency { 
    public int otherMethod(); 
} 

public class MyHandler { 
    @AutoWired 
    private MyDependency myDependency; 

    public void someMethod() { 
    myDependency.otherMethod(); 
    } 
} 

而且在測試:

private MyDependency mockDependency; 
private MyHandler realHandler; 

@Before 
public void setup() { 
    mockDependency = Mockito.mock(MyDependency.class); 
    realHandler = new MyHandler(); 
    realhandler.setDependency(mockDependency); //but you might Springify this 
} 

@Test 
public void testSomeMethod() { 

    //specify behaviour of mock 
    when(mockDependency.otherMethod()).thenReturn(1); 

    //really call the method under test 
    realHandler.someMethod(); 
} 

關鍵是要真正調用測試方法,但嘲笑他們可能有任何依賴關係(其他如調用方法類)

如果這些其他類是您的應用程序的一部分,那麼他們會有自己的單元測試。

注意上面的代碼可以用更多的註釋被縮短,但我想讓它爲解釋的目的更明確的(而且我不記得什麼是註釋:))

+0

使用spring IOC創建一個實例。你沒有從春季國際奧委會受益。假設我需要注入另一項服務。我不能這樣做。我必須創建一個實例。 –