テストクラスが登録されておらず、イベントパブリッシャーであるSpringアプリケーションコンテキストから解決されたため、イベントは発生しません。
私は、BeanとしてSpringに登録され、テストの一部として解決された別のクラスでイベントが処理される場合の回避策を実装しました。それはかなりではありませんが、より良い解決策を見つけるために一日の最善の部分を無駄にした後、私はこれで今、満足しています。
私のユースケースは、RabbitMQコンシューマ内でメッセージを受信したときにイベントを発生させていました。なお、以下で構成されている:
ラッパークラス
注テスト
内容器から解決した後、コールバック関数に渡すテストから呼び出され
は、init()関数
public class TestEventListenerWrapper {
CountDownLatch countDownLatch;
TestEventWrapperCallbackFunction testEventWrapperCallbackFunction;
public TestEventListenerWrapper(){
}
public void Init(CountDownLatch countDownLatch, TestEventWrapperCallbackFunction testEventWrapperCallbackFunction){
this.countDownLatch = countDownLatch;
this.testEventWrapperCallbackFunction = testEventWrapperCallbackFunction;
}
@EventListener
public void onApplicationEvent(MyEventType1 event) {
testEventWrapperCallbackFunction.CallbackOnEventFired(event);
countDownLatch.countDown();
}
@EventListener
public void onApplicationEvent(MyEventType2 event) {
testEventWrapperCallbackFunction.CallbackOnEventFired(event);
countDownLatch.countDown();
}
@EventListener
public void onApplicationEvent(OnQueueMessageReceived event) {
testEventWrapperCallbackFunction.CallbackOnEventFired(event);
countDownLatch.countDown();
}
}
コールバックインタフェース
public interface TestEventWrapperCallbackFunction {
void CallbackOnEventFired(ApplicationEvent event);
}
ユニット構成テストで参照されるBeanを定義するテスト構成クラス。これが有用である前に、それが最後に
@Configuration
public class TestContextConfiguration {
@Lazy
@Bean(name="testEventListenerWrapper")
public TestEventListenerWrapper testEventListenerWrapper(){
return new TestEventListenerWrapper();
}
}
、のApplicationContextから豆を解決し、初期の(呼び出しユニットテスト自体)(次のステップを参照)のApplicationContextから分離し、initialsedする必要がありますは、アサーション基準を渡す関数です(これは、Beanをシングルトンとして登録していることを前提としています。これは、SpringのapplicationContextのデフォルトです)。コールバック関数はここで定義され、Init()にも渡されます。
@ContextConfiguration(classes= {TestContextConfiguration.class,
//..., - other config classes
//..., - other config classes
})
public class QueueListenerUnitTests
extends AbstractTestNGSpringContextTests {
private MessageProcessorManager mockedMessageProcessorManager;
private ChannelAwareMessageListener queueListener;
private OnQueueMessageReceived currentEvent;
@BeforeTest
public void Startup() throws Exception {
this.springTestContextPrepareTestInstance();
queueListener = new QueueListenerImpl(mockedMessageProcessorManager);
((QueueListenerImpl) queueListener).setApplicationEventPublisher(this.applicationContext);
currentEvent = null;
}
@Test
public void HandleMessageReceived_QueueMessageReceivedEventFires_WhenValidMessageIsReceived() throws Exception {
//Arrange
//Other arrange logic
Channel mockedRabbitmqChannel = CreateMockRabbitmqChannel();
CountDownLatch countDownLatch = new CountDownLatch(1);
TestEventWrapperCallbackFunction testEventWrapperCallbackFunction = (ev) -> CallbackOnEventFired(ev);
TestEventListenerWrapper testEventListenerWrapper = (TestEventListenerWrapper)applicationContext.getBean("testEventWrapperOnQueueMessageReceived");
testEventListenerWrapper.Init(countDownLatch, testEventWrapperCallbackFunction);
//Act
queueListener.onMessage(message, mockedRabbitmqChannel);
long awaitTimeoutInMs = 1000;
countDownLatch.await(awaitTimeoutInMs, TimeUnit.MILLISECONDS);
//Assert - assertion goes here
}
//The callback function that passes the event back here so it can be made available to the tests for assertion
private void CallbackOnEventFired(ApplicationEvent event){
currentEvent = (OnQueueMessageReceived)event;
}
}
- EDIT 1:上記は異なるアプローチで更新されましたので、アサーションは、テストに失敗しませんでした**
:サンプルコードはたCountDownLatch
- EDIT 2で更新されました
:私の
ApplicationListener<ContextClosedEvent>
はカサンドラ接続を閉じた場合、私はチェックするために必要なていました –