JMS 集成测试

JMS integration testing

我正在尝试为 JMS 服务编写集成测试,看起来像这样。

 @JmsListener(destination = "mailbox", containerFactory = "myFactory")
 public void receiveMessage(Email message) throws InterruptedException {
    try {
        sendEmail(message);
    }catch (Exception e){
        LOGGER.log(Level.SEVERE,"Failed to deliver email",e);
        Thread.sleep(TimeUnit.SECONDS.toSeconds(Optional.of(retryInterval).orElse(5)));
        throw e;
    }
}

private void sendEmail(Email message){
    ...............
}

首先,我可以模拟一下吗?我尝试模拟它,但是当我发送消息时,spring 引导应用程序正在调用实际的 JMS bean 而不是模拟的。好像这是不可能的。 即使这是不可能的,我是否可以至少 aoutowire bean 并以某种方式检查是否正在调用 receiveMessage 方法。此外,如果它被调用,sendEmail 部分应该被伪造,这样它就不会做任何工作。我有一些想法,例如创建一个用于测试的子类,但对其中任何一个都不满意。如果您能建议我更好的解决方法,那么想要吗?

一种方法是使用不同的配置文件进行开发、集成测试和生产,并相应地注释不同的组件和您的集成测试class。

@Component
@Profile("it")
public class MessageReceiverIT {

    @JmsListener(destination = "mailbox", containerFactory = "myFactory")
    public void receiveMessage(SimpleMessage email) {
        log.info("Integration test pretend to receive {}", email);
// (...)

这是使用与真实应用程序相同的应用程序 class 的集成测试,但如果收到消息,将调用 MessageReceiverIT.receiveMessage() 方法而不是生产组件:

@RunWith(SpringRunner.class)
@SpringBootTest(classes=Application.class)
@ActiveProfiles("it")
public class JmsIntegrationTest {

    @Inject
    ConfigurableApplicationContext context;

    @Test
    public void testSend() throws Exception{
        JmsTemplate jmsTemplate = context.getBean(JmsTemplate.class);
        jmsTemplate.convertAndSend("mailbox", new SimpleMessage("it", "we need more IT"));
// (...)

另请查看 Spring Boot Testing 以了解其他方法,例如使用 @TestConfiguration。我在示例中使用 Spring Boot,但如果您有 none Spring Boot 应用程序,应该有类似的方法。