Skip to main content

Module testing

Module testing 

Source
Expand description

A test harness — TestApp and TestResponse.

ⓘ
let app = TestApp::new(boot(Mode::Testing).await?)?;

app.get("/health/ready").await
    .assert_ok()
    .assert_json_path("database.status", "ok");

let user: UserView = app.get("/api/me").await.json();

A feature test is three lines — make a request, assert the status, assert something about the body — and anything longer is the harness leaking.

§It scopes the facades to this test

The container facades resolve through is process-wide, so booting one application per test used to race: two tests boot, the second wins, and the first resolves out of a container that has been replaced. The symptom is nothing is bound for rainier_config::repository::Config on a random subset of tests on a random subset of runs.

TestApp holds a FacadeScope, which overrides the global one for the thread the test runs on. So each test gets its own application and its own configuration, and they do not interfere.

#[tokio::test] uses a current-thread runtime, so a test and everything it awaits stay on that thread. Under #[tokio::test(flavor = "multi_thread")] a future can move, and after the move a facade resolves through whatever was installed globally — so a multi-threaded test wanting its own container should keep the work on one task, or install its application globally and not run in parallel with another that does.

Structs§

TestApp
A booted application, ready to be asked for responses.
TestResponse
One response, with its body already read.