测试的Java类(称为ServiceCaller
)具有:
@Autowired @Qualifier(value="serviceA")
SomeService serviceA;
@Autowired @Qualifier(value="serviceB")
SomeService serviceB;
(有一个doWork()
方法将检查条件并调用 A 或 B)。
如何将每个服务的模拟注入到适当的变量中?
我的朱尼特有这个:
@InjectMocks ServiceCaller classUnderTest = new ServiceCaller();
@Mock SomeService mockServiceA;
@Mock SomeService mockServiceB;
然而,当我运行测试以检查在正确条件下调用的服务 A/B 时,我得到空指针,因为尚未注入模拟。
显然,这是因为同一接口上的多个依赖项(SomeService
)。有没有办法在声明模拟服务时指定限定符?还是我需要为依赖项设置资源库并设置老式方式?
将模拟命名为 serviceA 和 serviceB 就足够了。来自 Mockito 文档:
属性 setter 注入;模拟将首先按类型解析,然后, 如果有多个相同类型的属性,则通过匹配 属性名称和模拟名称。
在您的示例中:
@InjectMocks ServiceCaller classUnderTest;
@Mock SomeService serviceA;
@Mock SomeService serviceB;
请注意,使用 @InjectMocks 时无需手动创建类实例。
尽管如此,我个人更喜欢使用构造函数注入依赖项。它使在测试中注入模拟变得更加容易(只需使用模拟调用构造函数 - 没有反射工具或@InjectMocks
(这很有用,但隐藏了某些方面))。除了使用 TDD 之外,可以清楚地看到测试类需要哪些依赖项,并且 IDE 还可以生成构造函数存根。
Spring 框架完全支持构造函数注入:
@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);
您可以使用"name"属性来定义实例,如下所示:
@Mock(name="serviceA") SomeService serviceA;
@Mock(name="serviceB") SomeService serviceB;
当你有相同类型的依赖关系时,由于相同类型的属性,mockito停止注入depedencies。要参照@osiris256通过以下方式解决此问题:
class ServiceLayer{
@Autowired
@Qualifier("bean1")
private InterfaceA typeA;
@Autowired
@Qualifier("bean2")
private InterfaceA typeB;
}
您的测试类应该是:
@RunWith(SpringRunner.class)
class ServiceLayerTest{
@Mock(name = "typeA")
private InterfaceA typeA;
@Mock(name = "typeB")
private InterfaceA typeB;
@InjectMocks
ServiceLayer serviceLayer;
@Before
public void initialiseBeforeTest(){
MockitoAnnotations.initMocks(this);
}
// here goes your test
@Test
public void test(){
// use your when then .....
}
}
注意:如果您使用的是SpringRunner并使用@MockBean这将不起作用,您必须替换为 @Mock(name=") 以引用@osiris256。