From 175ac99a428e383d76b92cb7e259f9fcc3cbe3a9 Mon Sep 17 00:00:00 2001 From: Janito Vaqueiro Ferreira Filho Date: Wed, 29 Sep 2021 23:48:26 -0300 Subject: [PATCH] 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 --- zebra-test/src/mock_service.rs | 45 +++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/zebra-test/src/mock_service.rs b/zebra-test/src/mock_service.rs index 984f8957..30900eda 100644 --- a/zebra-test/src/mock_service.rs +++ b/zebra-test/src/mock_service.rs @@ -694,6 +694,42 @@ impl ResponseSender { /// 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) { let _ = self.response_sender.send(response.into_result()); } @@ -733,11 +769,12 @@ impl ResponseResult for Response { } } -impl ResponseResult for Result +impl ResponseResult + for Result where - Error: std::error::Error + Send + Sync + 'static, + SourceError: Into, { - fn into_result(self) -> Result { - self + fn into_result(self) -> Result { + self.map_err(|source_error| source_error.into()) } }