wiremock-rs
wiremock-rs copied to clipboard
async `respond_with` / `Respond`
Thanks for wiremock! It seems that it's currently not possible to execute async code in the respond method or respond trait. It'd be useful to have it natively supported by wiremock.
Wasn't able to find a workaround, tried
.respond_with(move |req: &Request| {
let handle = tokio::runtime::Handle::current();
std::thread::spawn(move || {
handle.block_on(async {
// Some async call
});
})
.join()
.unwrap();
ResponseTemplate::new(200)
})
but that's blocking the tokio runtime since the test runs as #[tokio::test].
What kind of async tasks are you trying to perform in response_with?
It's some business logic, in this case it's tower::util::Oneshot calls.
I'll need an example a bit more concrete to understand if it makes sense to extend the library or not 😄
Personally I'd say it'd make sense to have callbacks be async in general unless there's a good reason to not do it. Reason being that it's easy to have a sync wrapper in an async context but it's hard the other way around.
In this specific case I'm testing the correct setup of a FHIR Subscription. The HTTP request flow looks like this. The relevant part is 9. and 10. where a handshake takes place.
Basically:
Client --[ HTTP POST Create Subscription ]--> Server
Server --[ HTTP POST Handshake ] --> Client
The library exposing the functionality has an async method create_subscription which should only return once the subscription was created in full, with a successful handshake. To test this I have two MockServer instances, one being the client and one being the server. The test then calls create_subscription and only after the subscription mock finished (the server mock returning the ResponseTemplate) it should do a mocked handshake call to the client so create_subscription returns. The communication inside the client to signal that the handshake arrived is made with tokio::Notify. In the tests I'm now also using Notify as a workaround (requires me to juggle a tokio::join! later in the test), but I'd like to directly use https://github.com/tokio-rs/axum/blob/main/examples/testing/src/main.rs#L64-L67 which is async.
Hey there, thanks for this great library! I recently ran into the same issue. Trying to call some async code from a custom responder. Basically, I am trying to create a mock to validate an HTTP payload and one of the libraries to parse multipart data is async. e.g.
struct CustomResponder;
impl wiremock::Respond for CustomResponder {
fn respond(&self, req: &wiremock::Request) -> wiremock::ResponseTemplate {
// ... some logic ...
// This is an async function so can't be used here
let multipart = multer::Multipart::with_reader(req.body.as_slice(), boundary);
// ... validate multipart data ...
}
A lot of http libraries have gone async so it would be useful to be able to use them
Just another example in case it helps: In the response method, I have to call another service (another mock which implements json rpc), which is async.