1
0
mirror of https://github.com/actix/actix-website synced 2024-11-23 16:31:08 +01:00

update testing docs to give less precedence to unit testing

This commit is contained in:
Rob Ede 2023-09-10 02:56:48 +01:00
parent e67443f4e8
commit c5a9579193
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933
6 changed files with 22 additions and 18 deletions

View File

@ -8,7 +8,7 @@ import CodeBlock from "@site/src/components/code_block.js";
Actix Web uses its own [`actix_web::error::Error`][actixerror] type and [`actix_web::error::ResponseError`][responseerror] trait for error handling from web handlers. Actix Web uses its own [`actix_web::error::Error`][actixerror] type and [`actix_web::error::ResponseError`][responseerror] trait for error handling from web handlers.
If a handler returns an `Error` (referring to the [general Rust trait `std::error::Error`][stderror]) in a `Result` that also implements the `ResponseError` trait, actix-web will render that error as an HTTP response with its corresponding [`actix_web::http::StatusCode`][status_code]. An internal server error is generated by default: If a handler returns an `Error` (referring to the [general Rust trait `std::error::Error`][stderror]) in a `Result` that also implements the `ResponseError` trait, Actix Web will render that error as an HTTP response with its corresponding [`actix_web::http::StatusCode`][status_code]. An internal server error is generated by default:
```rust ```rust
pub trait ResponseError { pub trait ResponseError {
@ -36,7 +36,7 @@ fn index(_req: HttpRequest) -> io::Result<NamedFile> {
} }
``` ```
See [the actix-web API documentation][responseerrorimpls] for a full list of foreign implementations for `ResponseError`. See [the Actix Web API documentation][responseerrorimpls] for a full list of foreign implementations for `ResponseError`.
## An example of a custom error response ## An example of a custom error response

View File

@ -10,7 +10,7 @@ A request handler is an async function that accepts zero or more parameters that
Request handling happens in two stages. First the handler object is called, returning any object that implements the [_Responder_][respondertrait] trait. Then, `respond_to()` is called on the returned object, converting itself to a `HttpResponse` or `Error`. Request handling happens in two stages. First the handler object is called, returning any object that implements the [_Responder_][respondertrait] trait. Then, `respond_to()` is called on the returned object, converting itself to a `HttpResponse` or `Error`.
By default actix-web provides `Responder` implementations for some standard types, such as `&'static str`, `String`, etc. By default Actix Web provides `Responder` implementations for some standard types, such as `&'static str`, `String`, etc.
> For a complete list of implementations, check the [_Responder documentation_][responderimpls]. > For a complete list of implementations, check the [_Responder documentation_][responderimpls].

View File

@ -6,15 +6,11 @@ import CodeBlock from "@site/src/components/code_block.js";
# Testing # Testing
Every application should be well tested. Actix Web provides tools to perform unit and integration tests. Every application should be well tested. Actix Web provides tools to perform integration tests against your applications and unit test tools for custom extractors and middleware.
## Unit Tests Actix Web provides a request builder type. [_TestRequest_][testrequest] implements a builder-like pattern. You can generate a `HttpRequest` instance with `to_http_request()` and call your handlers or extractors with it. Also see
For unit testing, actix-web provides a request builder type. [_TestRequest_][testrequest] implements a builder-like pattern. You can generate a `HttpRequest` instance with `to_http_request()` and call your handler with it. ## Integration Testing For Applications
<CodeBlock example="testing" file="main.rs" section="unit-tests" />
## Integration tests
There are a few methods for testing your application. Actix Web can be used to run the application with specific handlers in a real HTTP server. There are a few methods for testing your application. Actix Web can be used to run the application with specific handlers in a real HTTP server.
@ -30,12 +26,18 @@ If you need more complex application configuration, testing should be very simil
<CodeBlock example="testing" file="integration_two.rs" section="integration-two" /> <CodeBlock example="testing" file="integration_two.rs" section="integration-two" />
## Stream response tests ## Stream Response Testing
If you need to test stream generation, it would be enough to call [`into_parts()`][resintoparts] and convert the resulting body into a future and execute it, for example when testing [_Server Sent Events_][serversentevents]. If you need to test stream generation, it would be enough to call [`into_parts()`][resintoparts] and convert the resulting body into a future and execute it, for example when testing [_Server Sent Events_][serversentevents].
<CodeBlock example="testing" file="stream_response.rs" section="stream-response" /> <CodeBlock example="testing" file="stream_response.rs" section="stream-response" />
## Unit Testing Extractors
Unit testing has pretty limited value for applications, but can be useful when developing extractors, middleware, and responders. Given that, calling directly into handler functions **which are defined stand-alone, without using routing macros** (like `#[get("/")]`) is possible if you want to make assertions on custom `Responder`s.
<CodeBlock example="testing" file="main.rs" section="unit-tests" />
[serversentevents]: https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events [serversentevents]: https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events/Using_server-sent_events
[resintoparts]: https://docs.rs/actix-web/4/actix_web/struct.HttpResponse.html#method.into_parts [resintoparts]: https://docs.rs/actix-web/4/actix_web/struct.HttpResponse.html#method.into_parts
[actixdocs]: https://docs.rs/actix-web/4/actix_web/test/index.html [actixdocs]: https://docs.rs/actix-web/4/actix_web/test/index.html

View File

@ -8,7 +8,7 @@ slug: /
Actix Web lets you quickly and confidently develop web services in Rust and this guide will get you going in no time. Actix Web lets you quickly and confidently develop web services in Rust and this guide will get you going in no time.
The documentation on this website focuses primarily on the Actix Web framework. For information about the actor framework called Actix, check out the [Actix chapter][actix-chapter] (or the lower level [actix API docs][actix-docs]). Otherwise, head on to the [getting started guide][getting-started]. If you already know your way around and you need specific information you might want to read the [actix-web API docs][actix-web-docs]. The documentation on this website focuses primarily on the Actix Web framework. For information about the actor framework called Actix, check out the [Actix chapter][actix-chapter] (or the lower level [actix API docs][actix-docs]). Otherwise, head on to the [getting started guide][getting-started]. If you already know your way around and you need specific information you might want to read the [Actix Web API docs][actix-web-docs].
[getting-started]: https://actix.rs/docs/getting-started [getting-started]: https://actix.rs/docs/getting-started
[actix-web-docs]: https://docs.rs/actix-web [actix-web-docs]: https://docs.rs/actix-web

View File

@ -1,6 +1,7 @@
use actix_web::{HttpRequest, Responder}; use actix_web::{get, HttpRequest, Responder};
#[allow(dead_code)] #[allow(dead_code)]
#[get("/")]
async fn index(_req: HttpRequest) -> impl Responder { async fn index(_req: HttpRequest) -> impl Responder {
"Hello world!" "Hello world!"
} }
@ -8,13 +9,13 @@ async fn index(_req: HttpRequest) -> impl Responder {
// <integration-one> // <integration-one>
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use actix_web::{http::header::ContentType, test, web, App}; use actix_web::{http::header::ContentType, test, App};
use super::*; use super::*;
#[actix_web::test] #[actix_web::test]
async fn test_index_get() { async fn test_index_get() {
let app = test::init_service(App::new().route("/", web::get().to(index))).await; let app = test::init_service(App::new().service(index)).await;
let req = test::TestRequest::default() let req = test::TestRequest::default()
.insert_header(ContentType::plaintext()) .insert_header(ContentType::plaintext())
.to_request(); .to_request();
@ -24,7 +25,7 @@ mod tests {
#[actix_web::test] #[actix_web::test]
async fn test_index_post() { async fn test_index_post() {
let app = test::init_service(App::new().route("/", web::get().to(index))).await; let app = test::init_service(App::new().service(index)).await;
let req = test::TestRequest::post().uri("/").to_request(); let req = test::TestRequest::post().uri("/").to_request();
let resp = test::call_service(&app, req).await; let resp = test::call_service(&app, req).await;
assert!(resp.status().is_client_error()); assert!(resp.status().is_client_error());

View File

@ -1,4 +1,4 @@
use actix_web::{web, HttpResponse, Responder}; use actix_web::{get, web, HttpResponse, Responder};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Deserialize, Serialize, Debug)] #[derive(Deserialize, Serialize, Debug)]
@ -7,6 +7,7 @@ struct AppState {
} }
#[allow(dead_code)] #[allow(dead_code)]
#[get("/")]
async fn index(data: web::Data<AppState>) -> impl Responder { async fn index(data: web::Data<AppState>) -> impl Responder {
HttpResponse::Ok().json(data.get_ref()) HttpResponse::Ok().json(data.get_ref())
} }
@ -22,7 +23,7 @@ mod tests {
let app = test::init_service( let app = test::init_service(
App::new() App::new()
.app_data(web::Data::new(AppState { count: 4 })) .app_data(web::Data::new(AppState { count: 4 }))
.route("/", web::get().to(index)), .service(index),
) )
.await; .await;
let req = test::TestRequest::get().uri("/").to_request(); let req = test::TestRequest::get().uri("/").to_request();