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_folderto 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
customfield.