尝试对具有自定义RecordFilterStrategy的ConcurrentKafkaListenerContainerFactory进行单元测试,但是无法找到测试过滤器策略的最佳方法。
class ConsumerConfiguration {
@Bean
public ConcurrentKafkaListenerContainerFactory<String, Message> messageListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactory<String, Message> factory =
new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(consumerFactory());
factory.setRecordFilterStrategy(consumerRecord -> consumerRecord.value().getType().contains("MYFILTER"));
return factory;
}
}
单元测试
@Mock
KafkaProperties kafkaProperties;
ConsumerConfiguration configuration;
@Test
void testMessageListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactory<String, Message> actual =
configuration.messageListenerContainerFactory();
assertEquals(kafkaProperties.buildConsumerProperties(),
actual.getContainerProperties().getKafkaConsumerProperties());
}
尽管此代码适合于单元测试,但是不提供Custom RecordFilterStrategy的代码覆盖,即lambda函数,因此,如果有人已经对Kafka Listener Container Factory进行了单元测试/代码覆盖,那么最好的帮助是什么?进行处理。
答案 0 :(得分:0)
对于出厂配置的纯单元测试,其中的过滤器是
record -> record.value().contains("foo")
您可以执行以下操作...
@SpringBootTest
class So63239177ApplicationTests {
@Autowired
ConcurrentKafkaListenerContainerFactory<String, String> factory;
private int called;
@Test
void testFilter() throws Exception {
MethodKafkaListenerEndpoint<String, String> endpoint = new MethodKafkaListenerEndpoint<>();
endpoint.setBean(this);
endpoint.setMethod(getClass().getDeclaredMethod("listen", ConsumerRecord.class));
endpoint.setMessageHandlerMethodFactory(new DefaultMessageHandlerMethodFactory());
endpoint.setTopics("foo");
ConcurrentMessageListenerContainer<String, String> container = factory.createListenerContainer(endpoint);
@SuppressWarnings("unchecked")
MessageListener<String, String> messageListener =
(MessageListener<String, String>) container.getContainerProperties().getMessageListener();
messageListener.onMessage(new ConsumerRecord<>("foo", 0, 0L, null, "foo"));
assertThat(this.called).isEqualTo(0);
messageListener.onMessage(new ConsumerRecord<>("foo", 0, 0L, null, "bar"));
assertThat(this.called).isEqualTo(1);
}
public void listen(ConsumerRecord<String, String> in) {
this.called++;
}
}
编辑
这是一种稍微简单(甚至更干净)的方式...
@SpringBootTest
class So632391771ApplicationTests {
@Autowired
KafkaListenerAnnotationBeanPostProcessor<?, ?> bpp;
@Autowired
KafkaListenerEndpointRegistry registry;
@Test
void testFilter() throws Exception {
TestListener listener = new TestListener();
this.bpp.postProcessAfterInitialization(listener, "test");
ContainerProperties containerProperties = registry.getListenerContainer("test")
.getContainerProperties();
assertThat(containerProperties.getGroupId()).isEqualTo("test");
@SuppressWarnings("unchecked")
MessageListener<String, String> messageListener =
(MessageListener<String, String>) containerProperties.getMessageListener();
messageListener.onMessage(new ConsumerRecord<>("foo", 0, 0L, null, "foo"));
assertThat(listener.called).isEqualTo(0);
messageListener.onMessage(new ConsumerRecord<>("foo", 0, 0L, null, "bar"));
assertThat(listener.called).isEqualTo(1);
}
}
class TestListener { // NOTE: Not a @Bean
int called;
@KafkaListener(id = "test", topics = "foo", autoStartup = "false")
public void listen(String in) {
this.called++;
}
}