Ben @TransactionalEvents
mevcut Bahar JUnit Testleri ile (@TransactionalTestExecutionListener
veya altsınıflamayla AbstractTransactionalUnit4SpringContextTests
ya aracılığıyla çalıştırın (Bahar 4.2 https://spring.io/blog/2015/02/11/better-application-events-in-spring-framework-4-2 bir özellik) test etmek çalışıyordum ama, zorunlu bir seçenek var gibi görünüyor - - ya bir @Rollback
şerhe testi veya olaylar ateş etmeyin testleri @Rollback mümkün olurken kimse @TransactionalEvents test etmek için iyi bir şekilde karşımıza HasTest @TransactionalEvents ve @Rollback
cevap
Stéphane Nicoll doğrudur: TransactionPhase
için eğer.? Sizin @TransactionalEventListener
, AFTER_COMMIT
olarak ayarlanmış, daha sonra otomatik rollback semantiği ile bir işlem testi olması hiçbir zaman bir anlam ifade etmemektedir çünkü olay asla ateş etti. Başka bir deyişle
, o işlem tamamlanmış asla eğer bir işlem tamamlanmış sonra ateş bir olay için hiçbir yolu yoktur.
Bu nedenle, etkinliğin gerçekten yapılmasını istiyorsanız, işlemin gerçekleştirilmesine izin vermeniz gerekir (ör., Test yönteminizi @Commit
ile ekleyerek). tamamlamak sonra temizlemek için, işlem işlediği sonra temizleme komut dosyalarını yürütmek için izole modunda @Sql
kullanmak gerekir. Örneğin, aşağıdaki (denenmemiş kodu) gibi bir şey sizin için işe yarayabilecek:
@Transactional
@Commit
@Sql(scripts = "/cleanup.sql", executionPhase = AFTER_TEST_METHOD,
config = @SqlConfig(transactionMode = TransactionMode.ISOLATED))
@Test
public void test() { /* ... */ }
Saygılarımızla,
Sam
Tamam, teşekkürler. Bu şekilde çalışmış olduğum gibi, benim yanlış anlaşılmamın bir kısmı, yayılmadan bağımsız olarak \ @Transactional çağrıların, en yüksek \ @ Transactional yöntemi tamamlanana kadar Olayı beklemeye devam etmesidir. – adam
Sam Brannen en solüsyonu (Bahar TestContext Çerçeve ait yazarı) neredeyse ile çalışır Adam'ın yorumuyla ilgili. Test yöntemi, işlem tamamlanmış sonra
Aslında @TransactionalEventListener
ile açıklanmış yöntemler olarak adlandırılır. Bunun nedeni, olayı gündeme getiren çağrı yönteminin, fiziksel değil, mantıksal bir işlem içinde yürütülmesidir. Bunun yerine, çağrı yöntemi yeni bir fiziksel işlem içinde yürütüldüğünde, @TransactionalEventListener
ile açıklamalı olan yöntemler, örneğin, test yöntemi işlemi gerçekleştirilmeden önce doğru zamanda çağrılır. biz aslında bu işlemlerin umurumda değil çünkü
Ayrıca, test yöntemleri @Commit
gerekmez. Ancak, çağrı yönteminin taahhüt edilen değişikliklerini geri almak için Sam Brannen tarafından açıklandığı gibi @Sql(...)
ifadesine ihtiyacımız var.
@TransactionalEventListener
varsayılan davranış) denir dinleyici İlk:
@Component
public class MyListener {
@TransactionalEventListener
public void when(MyEvent event) {
...
}
}
Sonra olayı yayınlayan uygulama hizmeti yukarıda sınıfı tarafından dinledi.Sam Brannen tarafından değil değil @Commit
şerhe önerdiği gibi @Service
@Transactional(propagation = Propagation.REQUIRES_NEW)
public class MyApplicationService {
public void doSomething() {
// ...
// publishes an instance of MyEvent
// ...
}
}
Nihayet test yöntemi: işlemler yöntem çağrılır her zaman (daha fazla ayrıntı için Spring Framework doc bakınız) yeni fiziksel olanlar olmak üzere yapılandırılmıştır dikkat edin Bu noktada gerekli: Eğer test kullandığı işlem geri ve kod emin belli bir parça olmak için
@Transactional
@Sql(scripts = "/cleanup.sql", executionPhase = AFTER_TEST_METHOD,
config = @SqlConfig(transactionMode = TransactionMode.ISOLATED))
@Test
public void test() {
MyApplicationService target = // ...
target.doSomething();
// the event is now received by MyListener
// assertions on the side effects of MyListener
// ...
}
o
:-) bir cazibe gibi çalışır Bu şekilde işlemeye çağrılacak sen, sen Bunu farklı bir şekilde test ediyorum. Çerçeveyi kendi kodunuzdan ziyade test edebileceğinizi iddia ediyorum. –
Kabul ettiğimden emin değilim, ama biraz düşüneceğim. @Rollback, ilk test durumuna geri dönmek için veritabanını sıfırlamaktır (testlerin birbiriyle etkileşime girme ihtimalinin daha az olduğundan emin olmak için). – adam
Ne yaptığını biliyorum. Sorun şu ki, işlemin gerçekleştiği bir olayı soruyorsunuz. Olmadı. –