我希望测试的Java类(称为ServiceCaller)具有:
@Autowired @Qualifier(value="serviceA")
SomeService serviceA;
@Autowired @Qualifier(value="serviceB")
SomeService serviceB;
(有一个doWork()方法,它将检查条件并调用A或B).
如何将每个服务的模拟注入适当的变量?
我的Junit有这个:
@InjectMocks ServiceCaller classUnderTest = new ServiceCaller();
@Mock SomeService mockServiceA;
@Mock SomeService mockServiceB;
然而,当我运行我的测试以检查在正确条件下调用的服务A / B时,我得到空指针,因为没有注入模拟.
显然它是因为多个依赖于同一个接口(SomeService).有没有办法在声明模拟服务时指定限定符?或者我是否需要为依赖项设置setter并设置旧的方式?
解决方法:
为mocks serviceA和serviceB命名应该足够了.来自Mockito documentation:
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时无需手动创建类实例.
不过我个人更喜欢使用构造函数注入依赖项.它可以更容易地在测试中注入模拟(只需用你的模拟调用构造函数 – 没有反射工具或@InjectMocks(这很有用,但隐藏了一些方面)).此外,使用TDD可以清楚地看到测试类需要哪些依赖项,IDE也可以生成构造函数存根.
Spring Framework完全支持构造函数注入:
@Bean
public class ServiceCaller {
private final SomeService serviceA;
private final SomeService serviceB;
@Autowired
public ServiceCaller(@Qualifier("serviceA") SomeService serviceA,
@Qualifier("serviceB") SomeService serviceB) { ... }
...
}
可以使用以下代码测试此代码:
@Mock SomeService serviceA;
@Mock SomeService serviceB;
//in a setup or test method
ServiceCaller classUnderTest = new ServiceCaller(serviceA, serviceB);