如何在模块/集成测试中禁用Spring SQS处理程序

时间:2017-05-18 07:01:43

标签: spring-boot-test spring-cloud-aws

我有一个spring boot应用程序,它只是通过一个带有@ SqsListener-annotated方法的组件“MessageHandler”监听SQS队列,并在消息到达时开始工作。

还有一个boot-starter-web依赖项,因为我们希望在生产中通过http获取健康状态和指标。

现在我想编写一个模块测试,它已经有一个应用程序上下文和autowires bean。我还发现了如何禁用测试不需要的Web服务器:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = NONE)

但是,MessageHandler bean也会被实例化并尝试连接到AWS,我想阻止它。

一个有效的解决方案是在src / test / java中使用@Primary注释进行测试实现,其handleMessage方法没有@SqsListener注释:

@Component
@Primary
public class TestMessageHandler implements MessageHandler {

    @Override
    public void handleMessage(final NewMessage newMessage) throws Exception {
        return null;
    }
}

但是现在我还要测试(真正的)MessageHandler bean,这意味着,我希望Spring实例化它并自动装配它的依赖项,但我仍然不希望@SqsListener注释变为活动状态,所以我可以在我的测试中像这样调用它:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = NONE)
public class IntegrationTest {

    @Autowired
    private RealMessageHandler messageHandler;


    @Test
    public void testHandleMessage() throws Exception {
        messageHandler.handleMessage(new NewMessage(...));
    }
}

所以我需要的是关闭spring-cloud-aws-starter模块中的魔法,该模块为RealMessageHandler中的handleMessage方法设置SQS监听器。

我是怎么做到的?

2 个答案:

答案 0 :(得分:0)

我遇到了类似的问题,并通过模拟SimpleMessageListenerContainer bean解决了该问题。我打算对多个集成测试执行此操作,因此为了使这些测试更具可读性,我创建了一个@TestConfiguration类,然后将其导入测试中。

这是我的配置类:


/**
 * Configuration class for integration test that do not need message listening capabilities.
 */
@TestConfiguration
public class MockMessageListenerConfiguration {

  @MockBean
  private SimpleMessageListenerContainer messageListenerContainer;

}

我这样使用它:

@SpringBootTest
@Import({MockMessageListenerConfiguration.class})
class BookingRepositoryIT {...}

此后,与AWS SQS相关的拒绝连接警告消失了。

答案 1 :(得分:-1)

@TestConfiguration
@EnableAutoConfiguration(exclude = {MessagingAutoConfiguration.class, CloudAutoConfiguration.class,
        ContextStackAutoConfiguration.class})
public class TestConfig {

    @Bean
    public SimpleMessageListenerContainer simpleMessageListenerContainer() {
        final SimpleMessageListenerContainerFactory factory = new SimpleMessageListenerContainerFactory();
        factory.setAutoStartup(false);
        factory.setAmazonSqs(amazonSQSAsync());
        final SimpleMessageListenerContainer simpleMessageListenerContainer = factory
                .createSimpleMessageListenerContainer();
        simpleMessageListenerContainer.setMessageHandler(messageHandler());
        return simpleMessageListenerContainer;
    }

    @Bean(name = "messageHandler")
    public QueueMessageHandler messageHandler() {
        return mock(QueueMessageHandler.class);
    }

    @Bean(name = "amazonSQSAsync")
    public AmazonSQSAsync amazonSQSAsync() {
        return mock(AmazonSQSAsync.class);
    }
}