2015-09-18 56 views
-1

對於我的使用案例之一,我只能嘲笑一個自動裝配的依賴項只有一個測試用例,而我想要其他測試使用原來的測試用例。Mockito with spring

public class A { 

    @Autowired 
    private B b; 
} 

Class TestA { 

    @Autowired 
    private A a; 

    void test1() { 
    //using B without mock. 
    } 

    void test2() { 
    // mock B b in A here 
    } 
} 

我想在一些特定的測試中模擬私有類變量'b'。我知道如果我必須在整個班級中嘲笑B,我可以使用@Mock,@InjectMocks和MockitoAnnotations.initMocks(),但是這會爲其他測試用例嘲笑'b'以及我想要的原始行爲。

+2

您可能有兩個差異測試類,一個模擬,另一個沒有模擬。 –

+0

@SubirKumarSao - 通常我們遵循只保留測試文件後綴* Test.java的習慣。保留2個不同的文件會讓其他人不理解。 – Amit

回答

0

您可以簡單地創建一個模擬對象,並將其暫時分配給變量b。喜歡的東西

public void test1() { 
    //normal test 
} 

在其他同時:

public void test2() { 
    try { 
     B autowiredObject = b; //saving the original reference 
     b = mock(B.class); 
     when(b.someGetFunction()).thenReturn("it is mocked"); 
     //rest of your test 
    } finally { 
     b = autowiredObject; 
    } 
} 

請注意finally條款。確保在測試期間恢復類狀態(autowired dependency)。這是一個非常重要的練習,否則測試中的失敗可能會在理論上影響同一班級的其他測試,這是您應該始終避免的。

+0

考慮到A類對象中B的實例與我們在測試中嘲笑的不一樣,它應該如何工作?我們沒有在A類的對象a中注入嘲弄的B,對吧? – Amit

+0

「我們還沒有注入嘲笑的B ...?」 - *是的,你做了。*在這裏:「b = mock(B.class);」 –

0

通常,您不使用Spring進行單元測試,而是依賴於模擬依賴關係並手動將它們注入到測試對象中。因此,一個簡單的測試方法是這樣的:

@Test 
public void testSomethingWithA() throws Exception { 
    // Arrange 
    A sut = new A(); 
    B mockedB = mock(B.class); 

    // inject B into A 
    Whitebox.setInternalState(sut, "b", mockedB); 

    // Act 
    Object retVal = sut.doSomething(); 

    // Assert 
    assertThat(retVal, is(equalTo(someExpectedValue))); 
} 

如果要注入真正的對象分爲A,而不是嘲笑對象(無論何種原因)的簡單與真實物體切換mockedB在Whitebox.setInternalState(...)

+0

我用JMockit的Deencapsulation.setField,它不工作讓我檢查如果Whitebox.setInternalState工作。 – Amit