【发布时间】:2018-05-15 09:54:45
【问题描述】:
我使用@EntityListeners 在保存到我的数据库之前和加载之后进行操作。
在我的 Listener 类中,我调用了 Ecryptor(它需要从配置文件中获取信息),因此不能静态调用加密器,需要将其注入到我的 Listener 中。对吧?
好吧,EntityListeners 中的注入不能立即完成,但您有一些方法可以做到这一点,例如使用 SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); 甚至这里显示的方法。 https://guylabs.ch/2014/02/22/autowiring-pring-beans-in-hibernate-jpa-entity-listeners/
很酷,问题是:没有一个解决方案支持单元测试!在运行我在模型监听器中注入的加密器的测试时,总是null。
这里SpringBeanAutowiringSupport does not inject beans in jUnit tests有一个解决方案来创建这个上下文并传递给一个实例化的对象,但它并没有解决我的问题,因为我有“注入”要添加到它。
有什么方法可以在我的测试中创建上下文并以某种方式将其传递给我的听众? 如果没有,我有什么方法可以为我的加密器创建一个静态方法,并且仍然可以访问 Environment API 来读取我的属性?
包监听器:
public class PackageListener{
@Autowired
Encryptor encryptor;
@PrePersist
public void preSave(final Package pack){
pack.setBic(encryptor.encrypt(pack.getBic()));
}
...
我的测试
@Test
@WithuserElectronics
public void testIfCanGetPackageById() throws PackageNotFoundException{
Package pack = packagesServiceFactory.getPackageService().getPackage(4000000002L);
}
打包服务
public Package getPackage(Long id) throws PackageNotFoundException{
Package pack = packageDao.find(id);
if (pack == null) {
throw new PackageNotFoundException(id);
}
return pack;
}
加密器:
public class Encryptor{
private String salt;
public Encryptor(String salt){
this.salt = salt;
}
public String encrypt(String string){
String key = this.md5(salt);
String iv = this.md5(this.md5(salt));
if (string != null) {
return encryptWithAesCBC(string, key, iv);
}
return string;
}
...
【问题讨论】:
-
如果是
null,您没有使用上下文。您的测试让我想知道您是否甚至在使用测试创建的上下文(我怀疑它是否会查看您在测试中所做的事情)。 -
感谢您的评论 @M.Deinum,我正在我的
BaseTest类中使用@ContextConfiguration(classes = {ApplicationConfiguration.class})创建一个上下文。除了Encryptor(从 EntityListener 调用)之外,所有注入和配置都正常工作 -
如前所述,我怀疑您是否真的在使用它来获取服务...
-
再次感谢!我明白你在说什么,但是,即使我将上下文传递给服务,之后我应该如何将它传递给加密器?
-
你不应该传递那些东西......我只是说你在测试中所做的事情与在实际代码中不同。您有某种服务工厂来获得测试服务这一事实暗示了我。您应该将依赖项注入到您的测试用例中,而不是使用其他对象来获取它们。但是这里的代码太少了,这里的东西充其量只是一个猜谜游戏。
标签: java spring-mvc junit dependency-injection entitylisteners