start
TestApp::start runs the app main builds, unchanged, with every broker connected in process and no server.
The harness starts the app in the service's own order: on_startup, then each broker's connect, then the subscriptions, then after_startup.
Each broker connects through its in-process transition, which performs no I/O and yields the broker's production connected form.
MemoryBroker has no server, so its in-process mode is its ordinary connect.
A networked broker provides the in-process mode under its crate's testing feature, which a service enables in [dev-dependencies].
A broker without it makes start fail with TestError::NoTransport naming the broker.
A failing on_startup fails start with TestError::Startup before any broker connects.
start_live runs the same app against a running stand, and with_state starts it with a state the test builds.
A test ends with shutdown.
Example
- Macros
- Manual
#[tokio::test]
async fn a_refused_order_is_dropped() -> Result<(), Box<dyn Error>> {
let tb = TestApp::start(app()).await?;
tb.broker::<MemoryBroker>()
.message(&Order { id: 13 })
.publish()
.await?;
tb.broker::<MemoryBroker>()
.subscriber("orders")
.assert_called_once()
.settled(HandlerOutcome::drop());
Ok(())
}
#[tokio::test]
async fn a_refused_order_is_dropped() -> Result<(), Box<dyn Error>> {
let tb = TestApp::start(app()).await?;
tb.broker::<MemoryBroker>()
.message(&Order { id: 13 })
.publish()
.await?;
tb.broker::<MemoryBroker>()
.subscriber("orders")
.assert_called_once()
.settled(HandlerOutcome::drop());
Ok(())
}