Improve `MockService` ergonomics for sending error responses (#2810)
* Remove `std::error::Error` constraint The generic `Error` type parameter doesn't have to implement the standard `Error` trait, so having that constraint only unnecessarily limits the types that can be used as an error for the service. * Implement automatic conversion into `Error` type Make the usage a little more ergonomic by not having to write manual error type conversions. * Add a documentation test for an error response Show an example that responds to a call to the service with an error. Co-authored-by: teor <teor@riseup.net>
This commit is contained in:
parent
18acec6849
commit
175ac99a42
|
@ -694,6 +694,42 @@ impl<Request, Response, Error> ResponseSender<Request, Response, Error> {
|
||||||
/// sent.
|
/// sent.
|
||||||
///
|
///
|
||||||
/// If this method is not called, the caller will panic.
|
/// If this method is not called, the caller will panic.
|
||||||
|
///
|
||||||
|
/// # Example
|
||||||
|
///
|
||||||
|
/// ```
|
||||||
|
/// # use zebra_test::mock_service::MockService;
|
||||||
|
/// # use tower::{Service, ServiceExt};
|
||||||
|
/// #
|
||||||
|
/// # let reactor = tokio::runtime::Builder::new_current_thread()
|
||||||
|
/// # .enable_all()
|
||||||
|
/// # .build()
|
||||||
|
/// # .expect("Failed to build Tokio runtime");
|
||||||
|
/// #
|
||||||
|
/// # reactor.block_on(async {
|
||||||
|
/// // Mock a service with a `String` as the service `Error` type.
|
||||||
|
/// let mut mock_service: MockService<_, _, _, String> =
|
||||||
|
/// MockService::build().for_unit_tests();
|
||||||
|
///
|
||||||
|
/// # let mut service = mock_service.clone();
|
||||||
|
/// # let task = tokio::spawn(async move {
|
||||||
|
/// # let first_call_result = (&mut service).oneshot(1).await;
|
||||||
|
/// # let second_call_result = service.oneshot(1).await;
|
||||||
|
/// #
|
||||||
|
/// # (first_call_result, second_call_result)
|
||||||
|
/// # });
|
||||||
|
/// #
|
||||||
|
/// mock_service
|
||||||
|
/// .expect_request(1)
|
||||||
|
/// .await
|
||||||
|
/// .respond("Received one".to_owned());
|
||||||
|
///
|
||||||
|
/// mock_service
|
||||||
|
/// .expect_request(1)
|
||||||
|
/// .await
|
||||||
|
/// .respond(Err("Duplicate request"));
|
||||||
|
/// # });
|
||||||
|
/// ```
|
||||||
pub fn respond(self, response: impl ResponseResult<Response, Error>) {
|
pub fn respond(self, response: impl ResponseResult<Response, Error>) {
|
||||||
let _ = self.response_sender.send(response.into_result());
|
let _ = self.response_sender.send(response.into_result());
|
||||||
}
|
}
|
||||||
|
@ -733,11 +769,12 @@ impl<Response, Error> ResponseResult<Response, Error> for Response {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Response, Error> ResponseResult<Response, Error> for Result<Response, Error>
|
impl<Response, SourceError, TargetError> ResponseResult<Response, TargetError>
|
||||||
|
for Result<Response, SourceError>
|
||||||
where
|
where
|
||||||
Error: std::error::Error + Send + Sync + 'static,
|
SourceError: Into<TargetError>,
|
||||||
{
|
{
|
||||||
fn into_result(self) -> Result<Response, Error> {
|
fn into_result(self) -> Result<Response, TargetError> {
|
||||||
self
|
self.map_err(|source_error| source_error.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue