【问题标题】:Spring-boot Redis JMS JUnitSpring-boot Redis JMS JUnit
【发布时间】:2021-07-18 21:08:54
【问题描述】:

我在我的 Spring Boot 应用程序中使用 Redis Server 作为消息代理。 有没有什么简单的方法来 Junit 我的发布和接收 API?

例如:

出版商:

public String publish(Object domainObj) {

    template.convertAndSend(topic.getTopic(), domainObj.toString());
    return "Event Published";
}

接收者:

公共类 Receiver 实现 MessageListener {

@Override
public void onMessage(Message message, byte[] bytes) {

    System.out.println("Consumed Message {}" + message);

}

}

我正在使用 JedisConnectionFactoryRedisMessageListenerContainerRedisTemplate 来实现

@Configuration
@EnableRedisRepositories
public class RedisConfig {

    @Bean
    public JedisConnectionFactory connectionFactory() {
        RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
        configuration.setHostName("localhost");
        configuration.setPort(6379);
        return new JedisConnectionFactory(configuration);
    }

    @Bean
    public RedisTemplate<String, Object> template() {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory());
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new JdkSerializationRedisSerializer());
        template.setValueSerializer(new JdkSerializationRedisSerializer());
        template.setEnableTransactionSupport(true);
        template.afterPropertiesSet();
        return template;
    }

    @Bean
    public ChannelTopic topic() {
        return new ChannelTopic("common-channel");
    }

    @Bean
    public MessageListenerAdapter messageListenerAdapter() {
        return new MessageListenerAdapter(new Receiver());
    }

    @Bean
    public RedisMessageListenerContainer redisMessageListenerContainer() {
        RedisMessageListenerContainer container = new RedisMessageListenerContainer();
        container.setConnectionFactory(connectionFactory());
        container.addMessageListener(messageListenerAdapter(), topic());
        return container;
    }

【问题讨论】:

  • 不,没有简单的方法可以尝试 local-redis 模块..

标签: junit redis mockito spring-jms spring-boot-test


【解决方案1】:

单元测试接收器和发布器的实现非常简单。
JUnit 5 加上 Mockito 扩展应该可以完成这项工作。

例如用于测试:

public String publish(Object domainObj) {
    template.convertAndSend(topic.getTopic(), domainObj.toString());
    return "Event Published";
}

我希望 topictemplate 是当前类的字段。 这些字段可以由构造函数设置。

所以你可以写一些东西来检查convertAndSend()最终是否使用正确的参数执行:

@Mock 
RedisTemplate<String, Object> templateMock;

@Test
void publish(){
   Topic topicFixture = new Topic(...);
   Object domainObjFixture = new FooBar(...);
   Publisher publisher = new Publisher(templateMock, topicFixture);
   //when
   publisher.publish(domainObjFixture);
   // then
   Mockito.verify(templateMock)
          .convertAndSend(topicFixture.getTopic(), domainObjFixture);      
}

但我认为这两个类的单元测试还不够,因为它从不测试最终的东西:Redis 后端执行的 JMS 处理。
特别是 RedisConfig 部分,您使用特定的东西设置为序列化程序,对处理有重要的副作用。
就我而言,我尝试始终为 Redis 后端内容编写集成或部分集成测试,以确保良好的无回归工具。

java embedded-redis library 非常适合。它允许启动一个redis服务器 在 localhost 上(适用于 Windows 和 Linux)。
启动和停止 redis 服务器很简单:

RedisServer redisServer = new RedisServer(6379);
redisServer.start();
// do some work
redisServer.stop();

移动@BeforeEach中的start()@AfterEach中的stop(),服务器就准备好了。
然后它仍然需要一些调整,以确保在测试期间使用本地 redis 服务器而不是“真正的”redis 服务器时,Spring 中指定的 redis 配置设置良好。设置起来并不总是那么简单,但一旦完成就很棒!

【讨论】:

    【解决方案2】:

    对此进行单元测试的最简单方法是使用embedded-redis 模块。您所做的是在BeforeAll 中您可以启动嵌入式Redis 并在AfterAll 方法中停止嵌入式Redis。

    你也可以PostConstructPreDestroy注解来完成这个。

    如果您正在寻找 Junit5,那么您可以在我的repo 此处找到代码

    在此处查看 BootstrapRedis 注释及其用法

    https://github.com/sonus21/rqueue/blob/7ef545c15985ef91ba719f070f7cc80745525047/rqueue-core/src/test/java/com/github/sonus21/rqueue/core/RedisScriptFactoryTest.java#L40

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-18
      • 1970-01-01
      • 1970-01-01
      • 2019-03-24
      • 2023-04-02
      • 2018-06-06
      • 2017-01-31
      • 2018-09-06
      相关资源
      最近更新 更多