Rocket - Custom configuration and injecting (overriding) values in tests
- We would like to have some custom configuration values for the application. (e.g. database address, API key for email sending service, folder to save uploaded imagesetc.)
- During testing we would like to set these values separately. e.g. for each test we create a temporary folder and then set the custom variable of the upload_folder to that value.
- This will keep our environment clean and the test will be independent.
- We can add those custom configuration values to Rocket.toml:
examples/rocket/config-with-tests/Rocket.toml
[debug] custom = "In Rocket.toml"
- We can then create a struct describing these parameters (MyConfig in our example) and we can use .attach(AdHoc::config::
()) to make Rocket read these values. - In each route we can use config: &State
to get the configuration values.
- In the tests we can override specific configuration values before we create the client.
let provider = Config::figment().merge(("custom", "In Test 1")); let app = super::rocket().configure(provider); let client = Client::tracked(app).unwrap();
examples/rocket/config-with-tests/src/main.rs
#[macro_use] extern crate rocket; use rocket::response::content; use rocket::{fairing::AdHoc, State}; use serde::Deserialize; #[derive(Deserialize)] struct MyConfig { custom: String, } #[get("/")] fn index(config: &State<MyConfig>) -> content::RawHtml<String> { content::RawHtml(format!("Custom: {}", config.custom)) } #[launch] fn rocket() -> _ { rocket::build() .mount("/", routes![index]) .attach(AdHoc::config::<MyConfig>()) } #[cfg(test)] mod test { use rocket::config::Config; use rocket::http::Status; use rocket::local::blocking::Client; #[test] fn home() { let client = Client::tracked(super::rocket()).unwrap(); let response = client.get("/").dispatch(); assert_eq!(response.status(), Status::Ok); let html = response.into_string().unwrap(); assert_eq!(html, "Custom: In Rocket.toml"); } #[test] fn test_1() { let provider = Config::figment().merge(("custom", "In Test 1")); let app = super::rocket().configure(provider); let client = Client::tracked(app).unwrap(); let response = client.get("/").dispatch(); assert_eq!(response.status(), Status::Ok); let html = response.into_string().unwrap(); assert_eq!(html, "Custom: In Test 1"); } #[test] fn test_2() { let provider = Config::figment().merge(("custom", "In Test 2")); let app = super::rocket().configure(provider); let client = Client::tracked(app).unwrap(); let response = client.get("/").dispatch(); assert_eq!(response.status(), Status::Ok); let html = response.into_string().unwrap(); assert_eq!(html, "Custom: In Test 2"); } }
- This will ensure that each test will have its own value for this custom field.