我想测试的 Java 类(称为 ServiceCaller
)有这个:
@Autowired @Qualifier(value="serviceA")
SomeService serviceA;
@Autowired @Qualifier(value="serviceB")
SomeService serviceB;
(有一个 doWork()
方法将检查条件并调用 A 或 B)。
如何将每个服务的模拟注入(inject)到适当的变量中?
我的Junit有这个:
@InjectMocks ServiceCaller classUnderTest = new ServiceCaller();
@Mock SomeService mockServiceA;
@Mock SomeService mockServiceB;
然而,当我运行测试以检查在正确条件下调用的服务 A/B 时,我得到空指针,因为尚未注入(inject)模拟。
显然是因为对同一接口(interface) (SomeService
) 的多个依赖项。有没有办法在声明模拟服务时指定限定符?还是我需要为依赖项设置 setter 并设置老式方式?
最佳答案
将模拟命名为 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 时无需手动创建类实例。
尽管如此,我个人更喜欢使用构造函数注入(inject)依赖项。它使在测试中注入(inject)模拟变得更容易(只需使用模拟调用构造函数 - 无需反射工具或 @InjectMocks
(这很有用,但隐藏了某些方面))。另外使用 TDD可以清楚地看到测试类需要哪些依赖项,并且 IDE 可以生成您的构造函数 stub 。
Spring Framework 完全支持构造函数注入(inject):
@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);
关于java - 如何注入(inject)同一接口(interface)的多个模拟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21054057/