2015-11-30 78 views
15

代碼:@RabbitListener方法測試

RabbitMQListener:

@Component 
public class ServerThroughRabbitMQ implements ServerThroughAMQPBroker { 
    private static final AtomicLong ID_COUNTER=new AtomicLong(); 
    private final long instanceId=ID_COUNTER.incrementAndGet(); 


    @Autowired 
    public ServerThroughRabbitMQ(UserService userService,LoginService loginService....){ 
.... 
    } 

    @Override 
    @RabbitListener(queues = "#{registerQueue.name}") 
    public String registerUserAndLogin(String json) { 
     ..... 
    } 

SERVERCONFIG:

@Configuration 
public class ServerConfig { 
    @Value("${amqp.broker.exchange-name}") 
    private String exchangeName; 
    @Value("${amqp.broker.host}") 
    private String ampqBrokerHost; 
    @Value("${amqp.broker.quidco.queue.postfix}") 
    private String quidcoQueuePostfix; 
    @Value("${amqp.broker.quidco.queue.durability:true}") 
    private boolean quidcoQueueDurability; 
    @Value("${amqp.broker.quidco.queue.autodelete:false}") 
    private boolean quidcoQueueAutodelete; 

    private String registerAndLoginQuequName; 


    @PostConstruct 
    public void init() { 
     registerAndLoginQuequName = REGISTER_AND_LOGIN_ROUTING_KEY + quidcoQueuePostfix; 
    public String getRegisterAndLoginQueueName() { 
     return registerAndLoginQuequName; 
    } 

    public String getLoginAndCheckBonusQueueName() { 
     return loginAndCheckBonusQuequName; 
    } 



    @Bean 
    public ConnectionFactory connectionFactory() { 
     CachingConnectionFactory connectionFactory = new CachingConnectionFactory(ampqBrokerHost); 
     return connectionFactory; 
    } 

    @Bean 
    public AmqpAdmin amqpAdmin() { 
     return new RabbitAdmin(connectionFactory()); 
    } 

    @Bean 
    public TopicExchange topic() { 
     return new TopicExchange(exchangeName); 
    } 

    @Bean(name = "registerQueue") 
    public Queue registerQueue() { 
     return new Queue(registerAndLoginQuequName, quidcoQueueDurability, false, quidcoQueueAutodelete); 
    } 


    @Bean 
    public Binding bindingRegisterAndLogin() { 
     return BindingBuilder.bind(registerQueue()).to(topic()).with(REGISTER_AND_LOGIN_ROUTING_KEY); 
    } 

    } 

TestConfig:

@EnableRabbit 
@TestPropertySource("classpath:test.properties") 
public class ServerThroughAMQPBrokerRabbitMQIntegrationTestConfig { 
    private final ExecutorService=Executors.newCachedThreadPool(); 
    private LoginService loginServiceMock=mock(LoginService.class); 
    private UserService userServiceMock =mock(UserService.class); 

    @Bean 
    public ExecutorService executor() { 
     return executorService; 
    } 

    @Bean 
    public LoginService getLoginServiceMock() { 
     return loginServiceMock; 
    } 

    @Bean 
    public UserService getUserService() { 
     return userServiceMock; 
    } 

    @Bean 
    @Autowired 
    public SimpleRabbitListenerContainerFactory rabbitListenerContainerFactory(ConnectionFactory connectionFactory) { 
     SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory(); 
     factory.setConnectionFactory(connectionFactory); 
     factory.setMaxConcurrentConsumers(5); 
     return factory; 
    } 

    @Bean 
    @Autowired 
    public RabbitTemplate getRabbitTemplate(ConnectionFactory connectionFactory) { 
     final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory); 
     return rabbitTemplate; 
    } 

    @Bean 
    public ServerThroughRabbitMQ getServerThroughRabbitMQ() { 
     return new ServerThroughRabbitMQ(userServiceMock, loginServiceMock,...); 
    } 

} 

集成測試:

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes ={ServerConfig.class,ServerThroughAMQPBrokerRabbitMQIntegrationTestConfig.class}) 
@Category({IntegrationTest.class}) 
@TestPropertySource("classpath:test.properties") 
public class ServerThroughAMQPBrokerRabbitMQIntegrationTest { 
    final private ObjectMapper jackson = new ObjectMapper(); 
    @Autowired 
    private ExecutorService executor; 

    @Autowired 
    private ServerThroughRabbitMQ serverThroughRabbitMQ; 

    @Autowired 
    private RabbitTemplate template; 

    @Autowired 
    private TopicExchange exchange; 

    @Autowired 
    UserService userService; 

    @Autowired 
    LoginService loginService; 

    @Autowired 
    private AmqpAdmin amqpAdmin; 

    @Autowired 
    private ServerConfig serverConfig; 

    final String username = "username"; 
    final String email = "[email protected]"; 
    final Integer tcVersion=1; 
    final int quidcoUserId = 1; 
    final String jwt = ProcessLauncherForJwtPhpBuilderUnitWithCxtTest.EXPECTED_JWT; 


    @Before 
    public void cleanAfterOthersForMyself() { 
     cleanTestQueues(); 
    } 

    @After 
    public void cleanAfterMyselfForOthers() { 
     cleanTestQueues(); 
    } 

    private void cleanTestQueues() { 
     amqpAdmin.purgeQueue(serverConfig.getRegisterAndLoginQueueName(), false); 
    } 

    @Test 
    @Category({SlowTest.class,IntegrationTest.class}) 
    public void testRegistrationAndLogin() throws TimeoutException { 
     final Waiter waiter = new Waiter(); 

     when(userService.register(anyString(), anyString(), anyString())).thenReturn(...); 
     when(loginService....()).thenReturn(...); 


     executor.submit(() -> { 
      final RegistrationRequest request = new RegistrationRequest(username, email,tcVersion); 
      final String response; 
      try { 
       //@todo: converter to convert RegistrationRequest inside next method to json 
       response = (String) template.convertSendAndReceive(exchange.getName(), REGISTER_AND_LOGIN_ROUTING_KEY.toString(), jackson.writeValueAsString(request)); 
       waiter.assertThat(response, not(isEmptyString())); 

       final RegistrationResponse registrationResponse = jackson.readValue(response, RegistrationResponse.class); 
       waiter.assertThat(...); 
       waiter.assertThat(...); 

      } catch (Exception e) { 
       throw new RuntimeException(e); 
      } 
      waiter.resume(); 
     }); 

     waiter.await(5, TimeUnit.SECONDS); 
    } 

} 

當我運行測試separetly,一切正常,但是當我與其他測試運行沒有被使用的嘲笑ServerThroughRabbitMQ,所以一些春天的緩存強制使用舊兔子監聽器。

我試圖調試它,我可以看到,正確的bean被自動裝入到測試中,但由於某種原因舊監聽器正在使用(舊bean字段instanceId = 1新的mocked bean instanceId = 3)並測試失敗不知道它是如何可能的,所以如果現有的舊bean,我假設得到一個自動裝載異常)。

我試圖用@DirtiesContext BEFORE_CLASS,但面對anoter問題(見here

+0

你有機會通過git分享你的項目問題部分(這將是非常有用的檢查這個測試與其他實驗)? – Sergii

+0

你有沒有找到一個滿意的解決方案? – geld0r

回答

2

的RabbitMQ和集成測試是很難的,因爲兔子MQ保持某種狀態: - 在隊列 從以前的測試消息 - 從以前的測試監聽器上的隊列

還在聽

有幾種方法:

  • 清除你之前的所有隊列開始測試(可能是世界衛生大會T優通過cleanTestQueues()的意思)
  • 刪除所有隊列(或使用臨時隊列),並重新創建它們每個測試
  • 之前使用兔管理員REST API殺死聽衆或先前測試的連接
  • 刪除虛擬主機並重新創建infrasture爲每個測試(這是最殘酷的方式)