问题描述
我在 Spring Boot 应用程序中使用 Redis 服务器作为消息代理。 有没有什么简单的方法可以对我的发布和接收 API 进行 Junit?
例如:
出版商:
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);
}
}
我正在使用 JedisConnectionFactory
和 RedisMessageListenerContainer
以及 Redistemplate
进行我的实现
@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;
}
解决方法
单元测试接收器和发布器的实现非常简单。
JUnit 5 加上 Mockito 扩展应该可以完成这项工作。
例如用于测试:
public String publish(Object domainObj) {
template.convertAndSend(topic.getTopic(),domainObj.toString());
return "Event Published";
}
我希望 topic
和 template
是当前类的字段。
这些字段可以由构造函数设置。
所以你可以写一些东西来检查 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 服务器
在本地主机上(适用于 Windows 和 Linux)。
启动和停止 redis 服务器就这么简单:
RedisServer redisServer = new RedisServer(6379);
redisServer.start();
// do some work
redisServer.stop();
移动 start()
中的 @BeforeEach
和 stop()
中的 @AfterEach
,服务器就准备好了。
然后它仍然需要一些调整以确保在使用本地 redis 服务器而不是“真实”redis 服务器的测试期间,Spring 中指定的 redis 配置设置良好。设置并不总是简单,但完成后很棒!
进行单元测试的最简单方法是使用 embedded-redis
模块。您所做的是在 BeforeAll
中您可以启动嵌入式 Redis 并在 AfterAll
方法中停止嵌入式 Redis。
您还可以通过 PostConstruct
PreDestroy
批注来完成此操作。
如果您正在寻找 Junit5,那么您可以在我的 repo 中找到代码
在此处查看 BootstrapRedis 注释及其用法