java - 使用 Spring 在多模块 Maven 项目中进行集成测试
问题描述
我有一个包含多个模块(父、服务、updater1、updater2)的多模块 maven 项目。@SpringBootApplication 在“服务”模块中,其他没有工件。
'updater1' 是一个具有 Kafka 侦听器和 http 客户端的模块,当接收到 kafka 事件时,会向外部 API 发起请求。我想在这个模块中创建集成测试testcontainers
,所以我创建了容器和一个 Kafka 生产者来向我的消费者发送一个 KafkaTemplate。
我的问题是 Kafka 生产者自动装配为 null,因此测试会抛出 NullPointerException。我想应该是Spring配置的问题,但是找不到问题。你能帮助我吗?谢谢!
这是我的测试课:
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {KafkaConfiguration.class, CacheConfiguration.class, ClientConfiguration.class})
public class InvoicingTest {
@ClassRule
public static final Containers containers = Containers.Builder.aContainer()
.withKafka()
.withServer()
.build();
private final MockHttpClient mockHttpClient =
new MockHttpClient(containers.getHost(SERVER),
containers.getPort(SERVER));
@Autowired
private KafkaEventProducer kafkaEventProducer;
@BeforeEach
@Transactional
void setUp() {
mockHttpClient.reset();
}
@Test
public void createElementSuccesfullResponse() throws ExecutionException, InterruptedException, TimeoutException {
mockHttpClient.whenPost("/v1/endpoint")
.respond(HttpStatusCode.OK_200);
kafkaEventProducer.produce("src/test/resources/event/invoiceCreated.json");
mockHttpClient.verify();
}
这是事件制作者:
@Component
public class KafkaEventProducer {
private final KafkaTemplate<String, String> kafkaTemplate;
private final String topic;
@Autowired
KafkaInvoicingEventProducer(KafkaTemplate<String, String> kafkaTemplate,
@Value("${kafka.topic.invoicing.name}") String topic){
this.kafkaTemplate = kafkaTemplate;
this.topic = topic;
}
public void produce(String event){
kafkaTemplate.send(topic, event);
}
}
解决方案
您还没有详细说明KafkaEventProducer
是如何实现的(它是一个@Component
吗?),您的测试类也没有用@SpringBootTest
和 runner注释@RunWith
。
使用 Apache KakfaProducer 查看此示例:
import org.apache.kafka.clients.producer.KafkaProducer;
public void sendRecord(String topic, String event) {
try (KafkaProducer<String, byte[]> producer = new KafkaProducer<>(producerProps(bootstrapServers, false))) {
send(producer, topic, event);
}
}
在哪里
public void send(KafkaProducer<String, byte[]> producer, String topic, String event) {
try {
ProducerRecord<String, byte[]> record = new ProducerRecord<>(topic, event.getBytes());
producer.send(record).get();
} catch (InterruptedException | ExecutionException e) {
fail("Not expected exception: " + e.getMessage());
}
}
protected Properties producerProps(String bootstrapServer, boolean transactional) {
Properties producerProperties = new Properties();
producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, bootstrapServer);
producerProperties.put(KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class.getName());
producerProperties.put(VALUE_SERIALIZER_CLASS_CONFIG, ByteArraySerializer.class.getName());
if (transactional) {
producerProperties.put(TRANSACTIONAL_ID_CONFIG, "my-transactional-id");
}
return producerProperties;
}
并bootstrapServers
取自 kafka 容器:
KafkaContainer kafka = new KafkaContainer();
kafka.start();
bootstrapServers = kafka.getBootstrapServers();
推荐阅读
- gettext - 在 Weblate 中本地化 Markdown 文件的最佳方法是什么?
- r - 为多组多级数据结构中的值创建空缺失行并计算组内行之间的差异
- excel - Visual Basic - for..next 和公式
- javascript - HtmlAgilityPack - 如何从标签中获取值进入 aspx.cs
- optaplanner - Optaplanner 解决垃圾收集问题
- android - 如何在 android 中为 ViewPager 的 TextView.setText 使用 ArrayString?
- android - 凌空中的 JsonArrayRequest 不发送参数,尽管相同的代码在我的其他应用程序中运行
- go - golang中的“未解决参考错误”
- swift - 为什么我在 viewDidLoad 中同步崩溃,有人知道发生这种情况的原因吗?
- string - 从字符串中获取整数月份值