2017-05-11 131 views
2

我正在寫一個具有2級依賴注入的類的測試用例。我爲1級依賴注入對象使用@Spy註解,我想模擬注入的第二級。但是,我一直在第二級獲得空指針異常。有什麼方法可以將模擬注入@Spy對象嗎?Mockito注入模擬間諜對象

public class CarTestCase{ 
    @Mock 
    private Configuration configuration; 

    @Spy 
    private Engine engine; 

    @InjectMocks 
    private Car car; 

    @Test 
    public void test(){ 

     Mockito.when(configuration.getProperties("")).return("Something"); 
     car.drive(); 
    } 

} 

public class Car{ 
    @Inject 
    private Engine engine; 

    public void drive(){ 
     engine.start(); 
    } 
} 

public class Engine{ 
    @Inject 
    private Configuration configuration; 

    public void start(){ 
     configuration.getProperties(); // null pointer exception 
    } 

} 
+0

有你'MockitoAnnotations.initmocks初始化嘲笑(這)' – pvpkiran

+0

沒有,但這與這個問題有什麼關係呢? – Wildchild

+0

@Wildchild @ Mildito使得Mockito能夠處理'@ Spy','@ Mock','@InjectMocks'等對象應該做的事情,所以如果你在構建'汽車'mocks之後應該注入...' – Antoniossss

回答

3

Mockito不能執行如此棘手的注射,因爲它不是注射框架。所以,你需要重構你的代碼,使其更具可測性。

public class Engine{ 
    private Configuration configuration; 

    @Inject 
    public Engine(Configuration configuration) { 
     this.configuration = configuration; 
    } 
    ........ 
} 

public class Car{ 
    private Engine engine; 

    @Inject  
    public Car(Engine engine) { 
     this.engine = engine; 
    } 
} 

在這種情況下,你必須處理的嘲弄和手動注:這很容易通過使用構造器注入完成

public class CarTestCase{ 

    private Configuration configuration; 

    private Engine engine; 

    private Car car; 

    @Before 
    public void setUp(){ 
     configuration = mock(Configuration.class); 
     engine = spy(new Engine(configuration)); 
     car = new Car(engine); 
    } 

    @Test 
    public void test(){ 

     Mockito.when(configuration.getProperties("")).return("Something"); 
     car.drive(); 
    } 

} 
+0

我明白了,但它是Spring框架中的一般設計,人們會將注入放在構造函數中?那麼注入註解的目的是什麼? – Wildchild

+0

@Wildchild的工作原理是一樣的。你不必顯式地調用構造函數,如果你在Spring上下文中,Spring會爲你做。此外,不建議使用字段注入,使用構造函數注入總是更好。 –