[英]Can I just inject super class when use dagger2 for dependency injection?
[英]How do I set up testing when there is a dependency injection from super class?
我的代码是这样设置的。
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
编写测试。 在测试中,我想使用注入的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,因为它会被其他扩展它的类使用。
根据我的课程设置方式,如何在测试时注入Store
?
不要使用字段注入。 使用构造函数注入。
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;
}
}
关于这个主题有一些争论,但是您的示例清楚地说明了使用字段注入使类更难测试的情况。
还值得注意的是
Spring团队普遍提倡构造函数注入
我通常使用以下模式解决这个问题:
abstract class BaseController {
private final Store store;
protected BaseController (Store store) {
this.store = store;
}
protected Store getStore() {
return this.store;
}
}
class MyController extends BaseController {
private final Validator validator;
@Inject
public MyController(Store store, Validator validator) {
super(store);
this.validator = validator;
}
public boolean someMethod() {
a = getStore().storingMethod();
b = validator.validate(a);
...
...
return true;
}
}
因此,无论任何可用的注入框架如何,都可以使用基类。
您可以使用ReflectionTestUtils
来设置您的字段值。
在你的pom.xml 中导入它:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.2.RELEASE</version>
<scope>test</scope>
</dependency>
使用它来设置您的商店:
@RunWith(MockitoJUnitRunner.class)
public class MyControllerTest() {
private MyController myController;
@Mock private Validator validator;
@Before
public void before() {
myController = new MyController(validator);
ReflectionTestUtils.setField(myController, "store", new YourTestStore());
// more testing
}
}
更多信息@ https://www.baeldung.com/spring-reflection-test-utils
另外,请注意,我认为这不是最佳实践。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.