Mockito 将模拟注入 Spy 对象

新手上路,请多包涵

我正在为一个具有 2 级依赖注入的类编写测试用例。我对 1 级依赖注入对象使用 @Spy 注释,我想模拟第二级注入。但是,我一直在第 2 级出现空指针异常。有什么办法可以将模拟注入 @Spy 对象吗?

 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
    }

}

原文由 Wildchild 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.5k
2 个回答

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();
    }

}

原文由 Sergii Bishyr 发布,翻译遵循 CC BY-SA 3.0 许可协议

我还徘徊了如何将模拟注入间谍。

以下方法将 不起作用

 @Spy
@InjectMocks
private MySpy spy;

但是当同时使用注释和手动模拟时,可以通过“混合”方法来实现所需的行为。以下完美运行:

 @Mock
private NeedToBeMocked needToBeMocked;

@InjectMocks
private MySpy mySpy;

@InjectMocks
private SubjectUnderTest sut;

@BeforeMethod
public void setUp() {
    mySpy = Mockito.spy(new MySpy());
    MockitoAnnotations.initMocks(this);
}

( SubjectUnderTest here depends on MySpy , and MySpy in its turn depends on NeedToBeMocked ).

UPD: 就我个人而言,我认为如果您不得不经常使用这种魔法,则可能表明您的类之间的依赖性存在问题,值得进行一些重构以改进您的代码。

原文由 Yoory N. 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题