pub struct TestClient { /* private fields */ }Expand description
Fluent HTTP client for integration tests.
Analogous to Spring Boot’s MockMvc or Django’s Client.
Fires requests through the full Axum middleware pipeline using
tower::ServiceExt::oneshot() – no TCP listener required.
Created by TestApp::build().
§Examples
let client = TestApp::new().routes(routes![handler]).build();
// GET request
client.get("/path").send().await.assert_ok();
// POST with JSON body
client.post("/items")
.json(&serde_json::json!({"name": "foo"}))
.send().await
.assert_status(201);
// PUT with header
client.put("/items/1")
.header("authorization", "Bearer token")
.json(&serde_json::json!({"name": "bar"}))
.send().await
.assert_ok();Implementations§
Source§impl TestClient
impl TestClient
Sourcepub const fn state(&self) -> &AppState
pub const fn state(&self) -> &AppState
Returns a reference to the AppState wired into this test app’s router.
Sourcepub fn advance_clock(&self, duration: Duration)
pub fn advance_clock(&self, duration: Duration)
Step the test clock forward by duration.
Only effective when the app was configured with a
crate::time::TickingClock via TestApp::with_clock. Calling this
with a crate::time::FixedClock or without any custom clock is a
safe no-op — time stays where it is.
This method only affects the wall-clock time reported by the
crate::time::Clock extractor. Tokio’s runtime timer (used by
tokio::time::sleep, tokio::time::Instant, etc.) is not affected.
use autumn_web::test::TestApp;
use autumn_web::time::TickingClock;
use chrono::{TimeZone, Utc};
use std::time::Duration;
let clock = TickingClock::starting_at(Utc.with_ymd_and_hms(2025, 1, 1, 0, 0, 0).unwrap());
let client = TestApp::new().with_clock(clock).build();
client.advance_clock(Duration::from_secs(86400)); // advance 1 daySourcepub fn into_router(self) -> Router
pub fn into_router(self) -> Router
Unwrap the underlying axum::Router out of the TestClient.
Sourcepub const fn probes(&self) -> &ProbeState
pub const fn probes(&self) -> &ProbeState
Return the crate::probe::ProbeState wired into this test app’s router.
Use this to drive readiness/liveness transitions in integration tests and verify the HTTP probe endpoints reflect state changes.
Sourcepub fn get(&self, uri: &str) -> RequestBuilder
pub fn get(&self, uri: &str) -> RequestBuilder
Start building a GET request.
Sourcepub fn post(&self, uri: &str) -> RequestBuilder
pub fn post(&self, uri: &str) -> RequestBuilder
Start building a POST request.
Sourcepub fn put(&self, uri: &str) -> RequestBuilder
pub fn put(&self, uri: &str) -> RequestBuilder
Start building a PUT request.
Sourcepub fn delete(&self, uri: &str) -> RequestBuilder
pub fn delete(&self, uri: &str) -> RequestBuilder
Start building a DELETE request.
Sourcepub fn patch(&self, uri: &str) -> RequestBuilder
pub fn patch(&self, uri: &str) -> RequestBuilder
Start building a PATCH request.
Sourcepub fn options(&self, uri: &str) -> RequestBuilder
pub fn options(&self, uri: &str) -> RequestBuilder
Start building an OPTIONS request (e.g. a CORS preflight).
Auto Trait Implementations§
impl !RefUnwindSafe for TestClient
impl !UnwindSafe for TestClient
impl Freeze for TestClient
impl Send for TestClient
impl Sync for TestClient
impl Unpin for TestClient
impl UnsafeUnpin for TestClient
Blanket Implementations§
Source§impl<T> AggregateExpressionMethods for T
impl<T> AggregateExpressionMethods for T
Source§fn aggregate_distinct(self) -> Self::Outputwhere
Self: DistinctDsl,
fn aggregate_distinct(self) -> Self::Outputwhere
Self: DistinctDsl,
DISTINCT modifier for aggregate functions Read moreSource§fn aggregate_all(self) -> Self::Outputwhere
Self: AllDsl,
fn aggregate_all(self) -> Self::Outputwhere
Self: AllDsl,
ALL modifier for aggregate functions Read moreSource§fn aggregate_filter<P>(self, f: P) -> Self::Output
fn aggregate_filter<P>(self, f: P) -> Self::Output
Source§fn aggregate_order<O>(self, o: O) -> Self::Outputwhere
Self: OrderAggregateDsl<O>,
fn aggregate_order<O>(self, o: O) -> Self::Outputwhere
Self: OrderAggregateDsl<O>,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>, which can then be
downcast into Box<dyn ConcreteType> where ConcreteType implements Trait.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>, which can then be further
downcast into Rc<ConcreteType> where ConcreteType implements Trait.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoSql for T
impl<T> IntoSql for T
Source§fn into_sql<T>(self) -> Self::Expression
fn into_sql<T>(self) -> Self::Expression
self to an expression for Diesel’s query builder. Read moreSource§fn as_sql<'a, T>(&'a self) -> <&'a Self as AsExpression<T>>::Expression
fn as_sql<'a, T>(&'a self) -> <&'a Self as AsExpression<T>>::Expression
&self to an expression for Diesel’s query builder. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> PolicyExt for Twhere
T: ?Sized,
impl<T> Read<Exclusive, BecauseExclusive> for Twhere
T: ?Sized,
Source§impl<T, Conn> RunQueryDsl<Conn> for T
impl<T, Conn> RunQueryDsl<Conn> for T
Source§fn execute<'conn, 'query>(
self,
conn: &'conn mut Conn,
) -> <Conn as AsyncConnectionCore>::ExecuteFuture<'conn, 'query>
fn execute<'conn, 'query>( self, conn: &'conn mut Conn, ) -> <Conn as AsyncConnectionCore>::ExecuteFuture<'conn, 'query>
Source§fn load<'query, 'conn, U>(
self,
conn: &'conn mut Conn,
) -> AndThen<Self::LoadFuture<'conn>, TryCollect<Self::Stream<'conn>, Vec<U>>>
fn load<'query, 'conn, U>( self, conn: &'conn mut Conn, ) -> AndThen<Self::LoadFuture<'conn>, TryCollect<Self::Stream<'conn>, Vec<U>>>
Source§fn load_stream<'conn, 'query, U>(
self,
conn: &'conn mut Conn,
) -> Self::LoadFuture<'conn>where
Conn: AsyncConnectionCore,
U: 'conn,
Self: LoadQuery<'query, Conn, U> + 'query,
fn load_stream<'conn, 'query, U>(
self,
conn: &'conn mut Conn,
) -> Self::LoadFuture<'conn>where
Conn: AsyncConnectionCore,
U: 'conn,
Self: LoadQuery<'query, Conn, U> + 'query,
Stream] with the returned rows. Read moreSource§fn get_result<'query, 'conn, U>(
self,
conn: &'conn mut Conn,
) -> AndThen<Self::LoadFuture<'conn>, LoadNext<Pin<Box<Self::Stream<'conn>>>>>
fn get_result<'query, 'conn, U>( self, conn: &'conn mut Conn, ) -> AndThen<Self::LoadFuture<'conn>, LoadNext<Pin<Box<Self::Stream<'conn>>>>>
Source§fn get_results<'query, 'conn, U>(
self,
conn: &'conn mut Conn,
) -> AndThen<Self::LoadFuture<'conn>, TryCollect<Self::Stream<'conn>, Vec<U>>>
fn get_results<'query, 'conn, U>( self, conn: &'conn mut Conn, ) -> AndThen<Self::LoadFuture<'conn>, TryCollect<Self::Stream<'conn>, Vec<U>>>
Vec with the affected rows. Read moreSource§impl<T> Scoped for T
impl<T> Scoped for T
Source§fn scope(ctx: &PolicyContext) -> ScopeQuery<'_, Self>
fn scope(ctx: &PolicyContext) -> ScopeQuery<'_, Self>
ScopeQuery for this type. Resolves the
registered scope at .load() time, not here.