我的代码是这样设置的。
abstract class BaseController {
@Inject Store store;
}
class MyController extends BaseController {
private final Validator validator;
@Inject
public MyController(Validator validator) {
this.validator = validator;
}
public boolean someMethod() {
a = store.storingMethod();
b = validator.validate(a);
...
...
return true;
}
}
现在我想为 myController
编写测试。在测试中,我想使用注入(inject)的Store
,但我想模拟出Validator
。
我尝试过这样的事情。
@RunWith(MockitoJUnitRunner.class)
public class MyControllerTest() {
private MyController myController;
@Mock private Validator validator;
@Before
public void before() {
myController = new MyController(validator);
}
}
我知道,如果我将 Store store
从 BaseController
移动到 MyController
,我可以在构造函数中初始化它(就像我为验证者做了)。但是,我希望在 Base 类中有 Store,因为它将被其他扩展它的类使用。
根据我的类设置方式,如何在测试时注入(inject) Store
?
最佳答案
不要使用字段注入(inject)。使用构造函数注入(inject)。
abstract class BaseController {
final Store store;
BaseController(Store store) {
this.store = store;
}
}
class MyController extends BaseController {
private final Validator validator;
@Inject
public MyController(Validator validator, Store store) {
super(store);
this.validator = validator;
}
}
关于这个主题存在一些争论,但您的示例清楚地说明了使用字段注入(inject)使类更难测试的情况。
Spring @Autowire on Properties vs Constructor
Dependency Injection: Field Injection vs Constructor Injection?
同样值得注意的是
The Spring team generally advocates constructor injection
关于java - 当存在来自父类(super class)的依赖注入(inject)时,如何设置测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59614345/