我在模型类中有一个验证方法,它从我无法控制的代码中调用。此验证方法具有来自依赖注入的参数。其中一个参数是单例(@Singleton
)类。
@Singleton
public class ObjValidation {
@Inject
public ObjValidation() {
objsCache = new HashSet<>();
}
public boolean exists(String obj) {
return objsCache.contains(obj) || lookupObj(obj);
}
...
}
正如您所看到的,如果对象未包含在缓存中,则此单例确实会对数据库执行查找。虽然测试此数据库不存在,但不应进行测试。因此,我正在尝试模拟exists()
方法,以便在不运行的情况下返回true。
我的第一个想法是,因为这是一个单例,如果我在运行它之前将单例注入我的测试用例,我会创建单例实例,因此可以spy
。
ObjValidation objValidation = spy(app.injector().instanceOf(ObjValidation.class));
doReturn(true).when(objValidation).exists(any());
但是,是的,spy
只返回一个副本,因此不会窥探实例化的单例。我需要用spy
副本替换单例实例,以使其以这种方式工作。
我该怎么做?
对测试用例的进一步说明:
在我的测试中(测试中的方法是register()
)我通过play框架的内置功能将scala.html视图窗体绑定到模型类。
public Result register() throws ResultMessageException {
...
Form<Registration> filledRegistrationForm = this.formFactory.form(Registration.class).bindFromRequest();
...
}
模型有一个验证方法,其参数可以按照播放文档中的说明进行注入:https://www.playframework.com/documentation/2.6.x/JavaForms#Custom-class-level-constraints-with-DI-support
@ValidateWithDI
public class Registration implements ValidatableWithDI<ValidationError> {
@Required
private String obj;
@Override
public ValidationError validate(ObjValidation objValidation) {
if (!objValidation.exists(obj)) {
return new ValidationError("obj");
}
return null;
}
}
框架在绑定表单时调用此验证方法。