• Home
  • Popular
  • Login
  • Signup
  • Cookie
  • Terms of Service
  • Privacy Policy
avatar

Posted by John Dev


10 Jan, 2025

Updated at 20 Jan, 2025

How do I get a the connection back during a unit test?

Hi I'm writing an web application using axum, rusqlite and minijinja. I've been able to setup the axum::Router with a State that holds the Jinja templates and a database connection to SQLite. It works when try it on the browser. I also would like to test the endpoints. I've been able to use oneshot to send a request and get a response in the tests.

However I've encountered a problem now that I want to write assertions against the database. IIUC constructing the axum::Router consumes the connection so I can't use it after the axum::Router has been constructed.

I'm unsure how to modify the code to be able to get the connection back after the application has processed the request. In the test context I'm using a in-memory database so I can't open a second connection to the database either. Any pointers to restructure the code?

Below are the relevant snippets of the application

// in lib.rs
#[derive(Clone)]
pub(crate) struct WebContext {
    templates: Environment<'static>,
    db: Arc<Mutex<Connection>>
}

pub fn new(db: Connection, template_dir: String) -> Router {
    let source = path_loader(template_dir);
    let mut env = Environment::new();
    env.set_loader(source);
    let db = Arc::new(Mutex::new(db));
    let ctx = WebContext { templates: env, db };
    Router::new()
        .route("/", get(handler::index))
        .route("/page/new", get(handler::new_page))
        .route("/page/", post(handler::page_create))
        .route("/upload/", post(handler::upload))
        .with_state(ctx)
}

and the test code

fn setup_db() -> Connection {
    let db = Connection::open_in_memory().expect("open db");
    let mut file = File::open("sql/schema.sql").expect("open schema file");
    let mut schema = String::new();
    file.read_to_string(&mut schema)
        .expect("reading schema file");
    db.execute_batch(&schema).expect("Initialized the schema.");
    db
}

fn setup_app(db: Connection) -> Router {
    bliki::new(db, "./template/".to_string())
}

#[tokio::test]
async fn test_create_article() {
    let db = setup_db();
    let app = setup_app(db);
    let mut params = HashMap::new();
    params.insert("title", "Some title");
    let body = serde_urlencoded::to_string(params).expect("encoding body");
    let req = Request::builder()
        .method("POST")
        .uri("/page/")
        .header("Content-Type", "application/x-www-form-urlencoded")
        .body(body)
        .unwrap();
    let res = app.oneshot(req).await.unwrap();

    assert_eq!(res.status(), StatusCode::OK);
    // The assertion that results in the problem arising
    let got_title: String = db.query_row_and_then("SELECT title FROM pages limit 1", [], |row| row.get(0)).expect("query title");
    assert_eq!(got_title, "Some Title");
}

1 post - 1 participant

Read full topic