【发布时间】:2016-06-10 14:57:26
【问题描述】:
我正在运行一些服务测试,并且我正在测试一个从使用泛型的类扩展而来的具体类。
服务层的示例设置如下:
public abstract class AbstractService <E extends AbstractEntity, IT extends AbstractItem> {
public void deleteAllItems(E entity) {
List<IT> items = new ArrayList<IT>(entity.getItems());
for(IT item : items) {
//Yada, yada
}
}
}
public class Service extends AbstractService<Entity, Item> {
}
public class OtherService() {
@Inject
private ServiceManager serviceManager;
public void deleteItems(Entity e) {
serviceManager.getService().deleteAllItems(e);
}
}
然后进行测试,我有以下内容:
public class Test {
private Service service;
private OtherService otherService;
private ServiceManager serviceManager;
@BeforeMethod
public void setup() {
serviceManager= mock(serviceManager.class);
service= mock(Service.class);
when(serviceManager.getService()).thenReturn(service);
otherService=injector.getInstance(OtherService.class);
}
@Test
public void test() {
Entity e = new Entity();
//Attach some items
otherService.deleteItems(e);
verify(service).deleteAllItems(e);
}
}
这应该调用存在的OtherService(我们正在使用注入来获取对象),然后调用方法deleteItems(),该方法又应该调用Service 上的deleteAllItems()。在我实现 Java 泛型之前,这工作正常,但由于我已经实现了 Java 泛型,Mockito 测试失败并出现以下异常:
java.lang.NoSuchMethodError: Service.deleteAllItems(实体;)V 在 Test.test(Test.java:XXX) org.mockito.exceptions.misusing.UnfinishedVerificationException: 此处缺少验证(模拟)的方法调用: -> 在 Test.test(Test.java:XXX)
正确验证示例: 验证(模拟).doSomething()
此外,此错误可能会出现,因为您验证了以下任一情况: final/private/equals()/hashCode() 方法。那些方法不能 存根/验证。
听起来好像找不到方法。我应该改为模拟 AbstractService 的抽象类还是我还缺少其他东西?
编辑
根据我对 Mockito 内部运作的了解,它创建了一个这样的实例:
public void AbstractService.deleteAllItems(Entity)
对于MockitoMethod 对象,Service.deleteAllItems()“未被调用”是有道理的,看起来 Mockito 假设只有基类被调用过。所以看起来我需要模拟基类。我将进一步调查,但如果有人有任何其他想法,我愿意接受建议
【问题讨论】:
-
对于单元测试,我建议不要使用
Injector。使用包私有构造函数创建被测类的实例。 -
这个@NamshubWriter 有什么具体原因吗?我们使用 Injection 来控制所使用的对象的实例,它对我们来说工作正常。将模拟对象绑定到注入非常简单,然后允许
Injector完成插入正确类的工作。我们只在这一个变体上遇到了问题。另外,如何解决多层注入?如果您不小心,可能会编写很多模拟规则,通过注入我们可以将其设置在一个位置,其他对象将使用这些实例。 -
依赖注入非常适合您的生产服务器/二进制文件和大型集成测试。对于单元测试,它会使您的测试变得缓慢、脆弱且难以理解。它还可以隐藏代码异味(例如具有太多依赖项的类)。测试应遵循 KISS
标签: java unit-testing generics mockito