wiremock
only.Expand description
§Create Django-style endpoints using wiremock
.
One possible use of this crate is to mock Django endpoints for development or testing. This may be convenient if you are otherwise developing in Rust, for example, and want to have CI run unit or integration tests that involve calls to such a service.
In order to be most useful as a mock, it needs to provide complete integrated Django endpoints:
- a HTTP server listening for requests.
- a store of data to serve.
- request parsing to determine result sets.
- Django formatted, paginated output.
The other modules in this crate provide most of this, when coupled
with wiremock
. This module is mostly concerned with tying
everything together into a whole.
§Overview
The main type in this module is Endpoint
, which is an
implementor of wiremock::Respond
, and can be mounted directly
on a wiremock::MockServer
. It takes a RowSource
which is responsible
for providing a snapshot of data to serve for each request. Each Endpoint
serves values of one type, and that type must always implement:
Sortable
so that"ordering"
requests can be processed.Filterable
so that filtering request can be processed ("__in"
,"__lt"
and so forth).IntoRow
so that rows of result data can be produced.
All three traits must always be implemented, because of the way in which cargo features interact - they are required to be stricly additive and adding type bounds decreases the set of types are permitted, and is thus subtractive.
The main functionality this module handles itself is pagination, and it provides a simple limit/offset model.
Example
use django_query::filtering::Filterable;
use django_query::mock::Endpoint;
use django_query::row::IntoRow;
use django_query::sorting::Sortable;
use std::sync::Arc;
use wiremock::{Mock, MockServer, matchers, http::Url};
#[derive(IntoRow, Filterable, Sortable)]
struct Foo {
#[django(sort, op(in, lt, gt))]
a: i32
}
let foos = (0..20i32).into_iter().map(|a| Foo { a }).collect::<Vec<_>>();
let server = MockServer::start().await;
Mock::given(matchers::method("GET"))
.respond_with(Endpoint::new(Arc::new(foos), Some(&server.uri())))
.mount(&server)
.await;
let u = format!("{}?limit=1&offset=5&a__lt=10&ordering=-a", server.uri());
let body: serde_json::Value = reqwest::get(&u)
.await
.expect("error getting response")
.json()
.await
.expect("error parsing response");
let prev = format!("{}/?limit=1&offset=4&a__lt=10&ordering=-a", server.uri());
let next = format!("{}/?limit=1&offset=6&a__lt=10&ordering=-a", server.uri());
assert_eq!(body, serde_json::json!{
{
"count": 10,
"next": next,
"previous": prev,
"results": [
{ "a": 4 }
]
}
});
Structs§
- Clone
Replace Field Source - Use a
Vec
valued field of aCloneReplace<T>
as aRowSource
. - Clone
Replace Persian RugTable Source - Use a table from a
persian_rug::Context
as aRowSource
- Endpoint
- A Django-style
wiremock
endpoint for a collection of objects. - Endpoint
With Context - A Django-style endpoint for a collection of objects that require a context value.
- Nested
Endpoint - A Django nested route.
- Nested
Endpoint Params - The construction parameters for
NestedEndpoint
- Nested
Endpoint With Context - A Django nested route for types that need a context value.
Enums§
- Mock
Error - An error produced by the mock endpoint.
Traits§
Functions§
- nested_
endpoint_ matches - Match a Django-style nested endpoint in wiremock