Testing¶
The testing feature ships KafkaTestBroker, an in-process stand-in for Kafka: the same
handlers and descriptors, no cluster. Enable it as a dev-dependency only:
Never enable this feature in production builds.
#[subscriber(KafkaTopic::new("payments"))]
async fn accept(payment: &Payment) -> HandlerResult {
if payment.amount == 0 {
return HandlerResult::drop();
}
HandlerResult::Ack
}
TestApp::publish waits until the handlers settle before returning, so assertions read
finished state - no sleeps:
let app = RustStream::new(AppInfo::new("payments", "0.1.0")).with_broker(
KafkaTestBroker::new(),
|b| {
b.include(accept);
},
);
let tb = TestApp::start(app).await.expect("start");
tb.broker::<KafkaTestBroker>()
.publish("payments", &Payment { amount: 100 })
.await
.expect("publish drives the handler to quiescence");
tb.broker::<KafkaTestBroker>()
.subscriber("payments")
.assert_called_once()
.with(&Payment { amount: 100 })
.settled(HandlerResult::Ack);
tb.shutdown().await.expect("shutdown");
What the test broker does not simulate¶
The in-process broker implements the core routing contract: exact topic-name fanout,
settlement, headers, and the partition-key header. It deliberately does not simulate Kafka
itself - consumer groups, partitions, committed positions, start offsets, rebalancing, and
retention are transport behavior. nack(true) redelivers immediately in-process, while the
real transport redelivers from the committed position on the next fetch.
Exercise the real semantics against a live cluster:
just brokers-up
KAFKA_TEST_URL=127.0.0.1:9092 cargo test --workspace --all-features -- --test-threads=1
The crate's own suites follow the same split: tests/testing_core.rs drives the in-process
broker, and tests/integration_rdkafka.rs plus the conformance lifecycle run only when
KAFKA_TEST_URL is set.