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.
|
||||
///
|
||||
/// 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>) {
|
||||
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
|
||||
Error: std::error::Error + Send + Sync + 'static,
|
||||
SourceError: Into<TargetError>,
|
||||
{
|
||||
fn into_result(self) -> Result<Response, Error> {
|
||||
self
|
||||
fn into_result(self) -> Result<Response, TargetError> {
|
||||
self.map_err(|source_error| source_error.into())
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue