2017-04-20 35 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的不同实现。