Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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.