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
:
[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::<MyConfig>())
to make Rocket read these values. -
In each route we can use
config: &State<MyConfig>
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();
#![allow(unused)] fn main() { #[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.