如何解决Spring依赖注入-私有字段-反模式?为什么它甚至起作用?
我通常是c#开发人员,但是现在正在使用Java,然后我看到在 private 属性上使用Spring进行了很多依赖注入,没有公开设置值的方法。我很惊讶这确实有效,但是我想可以通过反思吗?
这肯定是可怕的做法吗?!我看不到任何单元测试或检查类的人怎么可能知道需要从某个外部框架设置私有成员。
在进行单元测试时,您甚至将如何设置属性?还是只是单独使用课程?
我想您必须在单元测试中使用spring,这似乎实在是太过分了。当然,您无需IOC容器就可以进行单元测试?该类完全依赖于spring ...
我在这里错过了什么吗?
依赖注入是否不总是涉及某种公共的setter,并且在可能的情况下最好使用构造函数?还是我想念的关于Java的东西??
谢谢
解决方法
即使您有私有字段,也可以始终模拟注入的bean。您应该查看Spring文档中的@MockBean
。本质上,您可以执行以下操作:
@ExtendWith({SpringExtension.class})
class MyServiceTest{
@MockBean
private RepositoryInterface repository;
@Autowired
private MyService service;
}
假设RepositoryInterface
是在MyService
中注入的接口(而不是具体的类)。发生的事情是,如果您是从Spring Initialzr创建pom.xml的,那么JUnit5的SpringExtension
应该已经存在于您的依赖项中,它将使用另一个称为Mockito的框架为该接口构建一个模拟文件(也许看看对此)。然后,Spring IoC将在服务中注入创建的模拟。这适用于现场注入:
@Service
public class MyService{
@Autowired
private RepositoryInterface repositoryInterface
}
固定注入:
@Service
public class MyService{
private RepositoryInterface repositoryInterface
@Autowired
public void setRepository(RepositoryInterface repositoryInterface){
this.repositoryInterface = repositoryInterface;
}
}
或构造函数注入:
@Service
public class MyService{
private RepositoryInterface repositoryInterface
public MyService(RepositoryInterface repositoryInterface){
this.repositoryInterface = repositoryInterface;
}
}
基本上,最后一个是推荐的,因为这样,您的服务的依赖关系将是显式的。更多有关代码样式的信息。不建议使用字段注入,因为它会隐藏您的类依赖项。因此,建议使用构造函数注入来构建测试的方法如下:
@ExtendWith({SpringExtension.class})
class MyServiceTest{
@MockBean
private RepositoryInterface repository;
private MyService service;
@BeforeEach
void setup(){
service = new MyService(repository);
}
}
希望这有助于您理解。
,有基于字段的注入,基于setter的注入,基于注释的注入和基于构造函数的注入。基于构造函数的注入最适合测试,因为您可以轻松模拟所需的依赖关系。在可能的情况下,使用最终字段定义服务总是很好。
class MyService {
private final MyDependency dependency;
@Autowired // not needed,explicit just for this example
public MyService(MyDependency dependency) {
this.dependency = dependency;
}
}
,
是的,它有效。一些测试框架允许注入私有字段。
是的,它是反模式,增加了技术负担-易于编写,但难以维护此类代码,而不是编译时错误,您将遇到运行时错误。不要那样做使用构造函数注入。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。