我编写了以下集成测试类:
@ActiveProfiles("test")
@SpringBootTest
@Testcontainers
class DomainCourseMapperServiceApplicationIntegrationTest {
@Container
static final KafkaContainer kafkaContainer =
new KafkaContainer(DockerImageName.parse("confluentinc/cp-kafka:7.4.3"));
@DynamicPropertySource
static void overrideKafkaProperties(DynamicPropertyRegistry registry) {
registry.add("spring.kafka.bootstrap-servers", kafkaContainer::getBootstrapServers);
}
private static final String SCHEDULE_RAW_TOPIC = "schedule.raw";
private static final String SCHEDULE_DOMAIN_TOPIC = "schedule.domain";
KafkaTemplate<String, ScheduleRaw> scheduleRawProducer;
Consumer<String, ScheduleDomain> scheduleDomainConsumer;
@BeforeEach
void setUp() {
Map<String, Object> producerProps = KafkaTestUtils.producerProps(kafkaContainer.getBootstrapServers());
producerProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);
producerProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, JsonSerializer.class);
ProducerFactory<String, ScheduleRaw> producerFactory = new DefaultKafkaProducerFactory<>(producerProps);
scheduleRawProducer = new KafkaTemplate<>(producerFactory);
Map<String, Object> scheduleDomainConsumerProps = KafkaTestUtils.consumerProps(kafkaContainer.getBootstrapServers(), "schedule-domain-test-group", "false");
scheduleDomainConsumerProps.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);
scheduleDomainConsumerProps.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, JsonDeserializer.class);
scheduleDomainConsumerProps.put(ConsumerConfig.ENABLE_AUTO_COMMIT_CONFIG, false);
scheduleDomainConsumerProps.put(JsonDeserializer.TRUSTED_PACKAGES, "*");
ConsumerFactory<String, ScheduleDomain> scheduleDomainConsumerFactory = new DefaultKafkaConsumerFactory<>(scheduleDomainConsumerProps);
scheduleDomainConsumer = scheduleDomainConsumerFactory.createConsumer();
scheduleDomainConsumer.subscribe(List.of(SCHEDULE_DOMAIN_TOPIC));
}
@AfterEach
void tearDown() {
scheduleDomainConsumer.close();
}
@Test
void shouldConsumeScheduleRawAndProduceMappedScheduleDomainToDomainTopic() {
// Given
...
// When
scheduleRawProducer.send(SCHEDULE_RAW_TOPIC, key, event);
ConsumerRecord<String, ScheduleDomain> result = KafkaTestUtils.getSingleRecord(scheduleDomainConsumer, SCHEDULE_DOMAIN_TOPIC, Duration.ofSeconds(20));
// Then
...
}
}
当单独执行此测试类时,它会通过,但是当此测试类不单独运行时会出现问题,并且我在测试输出中得到以下堆栈跟踪:
java.lang.IllegalStateException: No records found for topic
at org.springframework.kafka.test.utils.KafkaTestUtils.getSingleRecord(KafkaTestUtils.java:181)
当测试类与其他测试类一起执行时(在项目中除了该测试类之外没有其他集成测试类 - 只有单元测试)它会失败,但只有在一种情况下 - 它不能首先执行。如果先执行此测试类,然后再执行其他测试类,则它通过。
我在
SCHEDULE_RAW_TOPIC
消费者中处理事件的行上添加了断点,以查看是否收到事件并且断点尚未触发 - 所以有两种可能性:scheduleRawProducer
或消费者的问题。
我还尝试在测试类之上添加
@DirtiesContext
,但没有解决问题。
有人遇到过类似的问题或知道解决办法吗?
正如 Artem 在他的评论中所写,解决方案是添加
@DirtiesContext
- 在问题中我提到我已经尝试将 @DirtiesContext
放在类上,但我将其作为最后一个注释(从底部开始)。
放置后:
@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_EACH_TEST_METHOD)
作为类问题顶部的第一个注释已得到解决。