我有一个接口:
public interface Service {
void doService();
}
还有一类:
public class ServiceUser {
@Inject
@Any
private Instance<Service> serviceImplementations;
public void work() {
serviceImplementations.forEach(service -> service.doService());
}
}
还有一个测试用例:
public class ServiceUserTest {
@Mock
private Service firstImpl;
@Mock
private Service secondImpl;
@InjectMocks
private ServiceUser serviceUser;
@Test
public void testAllImplementationsCalled() {
serviceUser.work();
verify(firstImpl).doService();
verify(secondImpl).doService();
}
}
当我运行测试用例时,我在ServiceUser
中得到一个NullPointerException
,其中在调试时serviceImplementations
为null。如果我在ServiceUser
中创建两个字段,我就可以注入两个实例(两个mock都被注入了,我在调试期间检查过)。
public class ServiceUser {
@Inject
@Any
private Instance<Service> serviceImplementations;
@EJB
private Service firstImpl;
@EJB
private Service secondImpl;
public void work() {
serviceImplementations.forEach(service -> service.doService());
}
}
我怎样才能做到这一点?
令人惊讶的是,我找不到一个好的现有伪造或测试双重Instance<T>
,就像在Instance<Service> serviceInstance = TestingInstance.of(firstImpl, secondImpl);
中一样。
你可能想创建一个——不是使用Mockito,而是作为一个实际的实现——并测试和使用它。这个接口相对较小,特别是如果你只是在select
方法上抛出UnsupportedOperationException,那么你就有了一个可以在所有测试用例中使用的实现。
因为它不是一个mock,所以你需要一个@InjectMocks的替代品;考虑到@InjectMocks随着依赖关系的变化而变得脆弱,这可能不是一件坏事。