Ich benutze @EntityListeners
, um Operationen vor dem Speichern in meinem Db und nach dem Laden zu machen. Innerhalb meiner Listener-Klasse rufe ich eine Ecryptor
(die Informationen aus der Konfigurationsdatei abrufen muss), so dass der Verschlüssler nicht statisch aufgerufen werden kann und in meinen Listener injiziert werden muss. Recht?@EntityListeners Injection + jUnit Testen
Nun, Injektionen in EntityListeners können nicht sofort durchgeführt werden, aber Sie haben einige Methoden, wie SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
oder sogar die hier gezeigte Methode zu tun. https://guylabs.ch/2014/02/22/autowiring-pring-beans-in-hibernate-jpa-entity-listeners/
Cool, das Problem ist: Keine der Lösungen unterstützt Unit Testing! Wenn Tests ausgeführt werden, die ich in meinem Modell injiziert habe, ist der Listener immer null
.
Hier SpringBeanAutowiringSupport does not inject beans in jUnit tests Es gibt eine Lösung, um diesen Kontext zu erstellen und an ein instanziiertes Objekt zu übergeben, aber es löst mein Problem nicht, da ich die "Injection" hinzufügen muss.
Kann ich einen Kontext in meinen Tests erstellen und irgendwie an meine Zuhörer weitergeben? Wenn nicht, kann ich eine statische Methode für meinen Encryptor erstellen und trotzdem Zugriff auf die Environment API haben, um meine Eigenschaften zu lesen?
Paket Zuhörer:
public class PackageListener{
@Autowired
Encryptor encryptor;
@PrePersist
public void preSave(final Package pack){
pack.setBic(encryptor.encrypt(pack.getBic()));
}
...
Mein Test
@Test
@WithuserElectronics
public void testIfCanGetPackageById() throws PackageNotFoundException{
Package pack = packagesServiceFactory.getPackageService().getPackage(4000000002L);
}
Paketdienst
public Package getPackage(Long id) throws PackageNotFoundException{
Package pack = packageDao.find(id);
if (pack == null) {
throw new PackageNotFoundException(id);
}
return pack;
}
Encryptor:
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;
}
...
Wenn es "null" ist, verwenden Sie den Kontext nicht. Ihr Test lässt mich fragen, ob Sie sogar den Kontext verwenden, der durch den Test erstellt wurde (ich bezweifle, dass Sie sehen, was Sie in Ihrem Test machen). –
Danke für Ihren Kommentar @ M.Deinum, ich erstelle einen Kontext mit '@ContextConfiguration (classes = {ApplicationConfiguration.class})' in meiner 'BaseTest' Klasse. Alle Injektionen und Konfigurationen funktionieren einwandfrei, abgesehen von dem "Encryptor" (vom EntityListener) –
Wie gesagt, ich bezweifle, dass Sie das tatsächlich verwenden, indem Sie einen Service erhalten ... –