2011-10-26 11 views
5

मैं वसंत में बनाई गई कस्टम घटनाओं का परीक्षण करने की कोशिश कर रहा हूं और एक दिलचस्प समस्या में भाग रहा हूं। यदि मैं StaticApplicationContext बनाता हूं और मैन्युअल रूप से पंजीकरण करता हूं और बीन्स तार करता हूं तो मैं ईवेंट ट्रिगर कर सकता हूं और श्रोता के माध्यम से प्रोग्राम प्रवाह (ApplicationEventPublisherAware लागू करता है) को श्रोता (ApplicationListener<?> लागू करता है) के माध्यम से देखता है।यूनिट परीक्षण स्प्रिंग एप्लिकेशन एवेन्ट्स - घटनाएं प्रकाशित हो रही हैं लेकिन श्रोताओं को गोलीबारी नहीं कर रही है?

फिर भी जब मैं संदर्भ SpringJunit4ClassRunner और @ContextConfiguration सब कुछ सिवाय इसके कि ApplicationEvents श्रोता में दिखाई नहीं दे रहे अच्छी तरह से काम का उपयोग कर बनाने के लिए एक JUnit परीक्षण बनाने की कोशिश (मैं पुष्टि की है कि वे प्रकाशित कर रहे हैं)।

क्या संदर्भ बनाने का कोई और तरीका है ताकि एप्लिकेशन एवेन्ट सही तरीके से काम कर सकें? स्प्रिंग इवेंट फ्रेमवर्क की इकाई परीक्षण के बारे में मुझे वेब पर बहुत कुछ नहीं मिला है।

+2

क्यों इस प्रश्न के लिए कोई जवाब नहीं देखते हैं: मैं अगर मेरे ApplicationListener<ContextClosedEvent> बंद कर दिया कैसेंड्रा कनेक्शन की जाँच करने के लिए आवश्यक था –

उत्तर

1

घटनाएं आग नहीं जाएंगी क्योंकि आपकी परीक्षा कक्षाएं वसंत आवेदन संदर्भ से पंजीकृत नहीं हैं और हल की गई हैं, जो घटना प्रकाशक है।

मैंने इस के लिए एक कार्यवाही लागू की है जहां घटना को एक और वर्ग में संभाला जाता है जो वसंत के साथ एक बीन के रूप में पंजीकृत होता है और परीक्षण के हिस्से के रूप में हल किया जाता है। यह सुंदर नहीं है, लेकिन एक बेहतर समाधान खोजने की कोशिश कर रहे दिन का सबसे अच्छा हिस्सा बर्बाद करने के बाद मैं अब इसके लिए खुश हूं।

एक खरगोश एमक्यू उपभोक्ता के भीतर एक संदेश प्राप्त होने पर मेरा उपयोग केस एक घटना को फायर कर रहा था। यह निम्न से बना है:

आवरण वर्ग

नोट 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); 
} 

यूनिट परीक्षण में संदर्भित बीन को परिभाषित करने के लिए एक परीक्षण कॉन्फ़िगरेशन क्लास। इससे पहले कि यह उपयोगी है, यह applicationContext से हल हो गई और initialsed जा करने के लिए (अगला चरण देखें)

@Configuration 
public class TestContextConfiguration { 
    @Lazy 
    @Bean(name="testEventListenerWrapper") 
    public TestEventListenerWrapper testEventListenerWrapper(){ 
     return new TestEventListenerWrapper(); 
    } 
} 

अंत में, इकाई परीक्षण ही कि 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; 
    } 
} 
  • संपादित करें 1: नमूना कोड CountDownLatch साथ अद्यतन किया गया है
  • संपादित 2: इस प्रकार के दावे परीक्षण असफल नहीं किया तो ऊपर एक अलग दृष्टिकोण के साथ अद्यतन किया गया था **
0

आप मैन्युअल रूप से एक संदर्भ बना सकते हैं।

उदाहरण के लिए:

@Test 
public void testSpringShutdownHookForCassandra(){ 
    ConfigurableApplicationContext ctx = new AnnotationConfigApplicationContext(CassandraConfig.class); 

    CassandraConnectionManager connectionManager = ctx.getBean(CassandraConnectionManager.class); 
    Session session = connectionManager.openSession(testKeySpaceName); 

    Assert.assertFalse(session.isClosed()); 
    ctx.close(); 

    Assert.assertTrue(session.isClosed()); 
} 
संबंधित मुद्दे