2017-05-11 132 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会为你做。此外,不建议使用字段注入,使用构造函数注入总是更好。 –