如何注入相同接口的多个模拟 [英] How to inject multiple mocks of the same interface

查看:184
本文介绍了如何注入相同接口的多个模拟的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望测试的Java类(称为 ServiceCaller )有:

The Java class (called ServiceCaller) I wish to test has this:

@Autowired @Qualifier(value="serviceA")
SomeService serviceA;

@Autowired @Qualifier(value="serviceB")
SomeService serviceB;

(有一个 doWork()方法将检查条件并调用A或B)。

(there's a doWork() method that will check a condition and call either A or B).

如何将每个服务的模拟注入适当的变量?

How do I inject a mock of each service into the appropriate variable?

我的 Junit 有:

@InjectMocks ServiceCaller classUnderTest = new ServiceCaller();

@Mock SomeService mockServiceA;
@Mock SomeService mockServiceB;

然而,当我运行测试以检查服务A / B是否在正确的条件下调用时,我得到了null指针因为没有注入mock。

Yet when I run my tests to check that service A/B called under the correct condition, I get null pointers as the mock hasn't been injected.

显然它是因为在同一个接口上有多个依赖项( SomeService )。有没有办法在声明模拟服务时指定限定符?或者我是否需要为依赖项设置setter并设置旧的方式?

Obviously its because of multiple dependencies on the same interface (SomeService). Is there a way to specify the qualifier when declaring the mock service? Or do I need to have setters for the dependencies and set the old fashioned way?

推荐答案

这应该足以命名你的模拟serviceA和serviceB。来自Mockito 文档

It should be enough to name your mocks serviceA and serviceB. From Mockito documentation:


Property setter injection; mocks将首先按类型解析,然后,
如果有多个相同类型的属性,则通过
属性名称和模拟名称的匹配。

Property setter injection; mocks will first be resolved by type, then, if there is several property of the same type, by the match of the property name and the mock name.

在你的例子中:

@InjectMocks ServiceCaller classUnderTest;

@Mock SomeService serviceA;
@Mock SomeService serviceB;

请注意,使用@InjectMocks时无需手动创建类实例。

Note that it is not necessary to manually create class instance when using @InjectMocks.

尽管我个人更喜欢使用构造函数注入依赖项。这样可以更容易地在测试中注入模拟(只需用你的模拟调用构造函数 - 没有反射工具或 @InjectMocks (这很有用,但隐藏了一些方面))。此外,使用 TDD 可以清楚地看到测试类需要哪些依赖项,IDE也可以生成构造函数存根。

Nevertheless I personally prefer injecting dependencies using constructor. It makes it easier to inject mocks in tests (just call a constructor with your mocks - without reflections tools or @InjectMocks (which is useful, but hides some aspects)). In addition using TDD it is clearly visible what dependencies are needed for the tested class and also IDE can generate your constructor stubs.

Spring Framework完全支持构造函数注入:

Spring Framework completely supports constructor injection:

@Bean
public class ServiceCaller {
    private final SomeService serviceA;
    private final SomeService serviceB;

    @Autowired
    public ServiceCaller(@Qualifier("serviceA") SomeService serviceA,
                         @Qualifier("serviceB") SomeService serviceB) { ... }

    ...
}

此代码可以通过以下方式测试:

This code can be tested with:

@Mock SomeService serviceA;
@Mock SomeService serviceB;

//in a setup or test method
ServiceCaller classUnderTest = new ServiceCaller(serviceA, serviceB); 

这篇关于如何注入相同接口的多个模拟的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆