2017-04-20 58 views
1

我有一個應用程序事件偵聽器,包含了函數:簡單的方法來測試彈簧onApplicationEvent

@Override 
public void onApplicationEvent(ContextRefreshedEvent event) { 
//do some stuff 
} 

我如何寫一個單元測試來模擬ContextRefreshedEvent,就像我的罐子被執行,並測試我的onApplicationEvent函數做了它應該做的事情?

回答

2

這是我能想到的最小的獨立示例。

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.ApplicationListener; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.event.ContextRefreshedEvent; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 

import java.util.concurrent.LinkedBlockingQueue; 

import static org.junit.Assert.assertEquals; 

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = {RefreshTest.MyConfig.class}) 
public class RefreshTest { 

    @Autowired 
    private MyListener listener; 

    @Test 
    public void test() { 
     assertEquals("Refresh should be called once",1, listener.events.size()); 
    } 

    public static class MyConfig { 
     @Bean 
     public MyListener listener() { 
      return new MyListener(); 
     } 
    } 

    public static class MyListener implements ApplicationListener <ContextRefreshedEvent> { 
     // you don't really need a threadsafe collection in a test, as the test main thread is also loading the spring contest and calling the handler, 
     // but if you are inside an application, you should be aware of which thread is calling in case you want to read the result from another thread. 
     LinkedBlockingQueue<ContextRefreshedEvent> events = new LinkedBlockingQueue<ContextRefreshedEvent>(); 
     public void onApplicationEvent(ContextRefreshedEvent event) { 
      events.add(event); 
     } 
    } 
} 

有測試處理器內,該處理器被調用的代碼之間的差異。不要將代碼直接放在處理程序中,而是將其放在另一個從處理程序調用的bean中,以便您可以在不使用處理程序的情況下測試邏輯(通過使用您創建的ContextRefreshedEvent來調用它)。刷新上下文時(通常是在加載時)會發送刷新事件,因此不需要測試該事件。如果它沒有在您的生產代碼中被調用,您通常會立即注意到。另外,在測試和生產之間,上下文的加載可能是不同的,所以即使你編寫了一個顯示處理程序被調用的測試,也不能保證它會在生產中被調用,除非你使用完全相同的@Configuration - 我幾乎從來沒有這樣做,因爲當我不希望我的測試使用AWS Queues和其他外部IO通道時,我經常會使用@Profile來實現一些配置/ bean的不同實現。