Writing Tests for Tauri Commands: How to Access and Manage State in Test Environments

223 Views Asked by At

lets say I have a state and a command like this

#[derive(Default)]
pub struct MyState {
  pub s: std::sync::Mutex<String>,
  pub t: std::sync::Mutex<std::collections::HashMap<String, String>>,
}

#[tauri::command]
fn hello_world(state: tauri::State<'_, MyState>) -> String {
  let mut s = state.s.lock().unwrap();
  s.push_str(" world");
  s.clone()
}

How do I access MyState when I want to write a test for hello_world function?

I haven't attempted any specific actions yet as I'm currently exploring how to approach testing for the hello_world function in Tauri. I'm seeking guidance on the correct methodology to access and manipulate the MyState struct within the testing environment. Could you provide assistance on how to effectively set up and conduct tests for Tauri commands involving state management?

1

There are 1 best solutions below

0
On

I have struggled with this myself. There is a "hidden" unstable feature called tauri::test, which, as far as I can tell, is virtually undocumented in the user docs, but it's documented in the reference on docs.rs.

You can see some examples here: docs.rs documentation, a snippet from the examples.

Because I also need it, I set up a small application with a working test here. Shortly:

Add the test feature in your Cargo.toml:

tauri = { version = "1.4", features = ["test"] }

You can now use tauri::test for setting up your mock application:

fn create_app<R: tauri::Runtime>(mut builder: tauri::Builder<R>) -> tauri::App<R> {
    builder
        .setup(|app| {Ok(())})
        .invoke_handler(tauri::generate_handler![greet])
        .build(tauri::generate_context!())
        .expect("failed to build app")
}


#[cfg(test)]
mod tests {
    use tauri::Manager;
    #[test]
    fn something() {
        let data = r#"{"name": "the test"}"#;
        let app = super::create_app(tauri::test::mock_builder());
        let window = app.get_window("main").unwrap();
        tauri::test::assert_ipc_response(
            &window,
            tauri::InvokePayload {
                cmd: "greet".into(),
                tauri_module: None,
                callback: tauri::api::ipc::CallbackFn(0),
                error: tauri::api::ipc::CallbackFn(1),
                inner: serde_json::from_str(data).unwrap(),
            },
            Ok("Hello, the test! You've been greeted from Rust!"),
        );
    }
}

If you want to test on my repo, simply install the app as usual and then run the tests:

pnpm install
cd src-tauri
cargo test

Remember that you won't test that the serialization is done correctly from the javascript side. For that, you will need end-to-end tests, which, fortunately, are in the user documentation.

Please let me know if this is enough for you. I know I didn't add a State example per-se, I can add a State example as well.