June 2024
I’m now in charge of a Tauri app and there is a lot of native Rust functionality that needs to be exposed to the JS side. Like any principled dev I want to write tests for my code.
The official documentation says one should write e2e tests with a UI simulation framework to test this functionality but that is way to cumbersome. I wanted unit tests for my Rust code. Also, I did not have stateless Rust functions, but functions where Tauri itself managed the state, so I needed to mock the entire Tauri app stack.
Credit where is due this Stack Overflow answer provided the info I was looking for.
However Tauri 1.6.7
broke this functionality and 1.6.8
fixed it by adding a new parameter.
Without further ado, first you need to add the test
feature in your Tauri dependency:
tauri = { version = "1.6.8", features = ["api-all", "updater", "test"] }
Then you can write your test like so:
#[cfg(test)]
mod tests {
use super::*;
use tauri::{
test::{mock_context, noop_assets, MockRuntime},
App,
};
fn before_each() -> Result<tauri::App<MockRuntime>, std::io::Error> {
let app = tauri::test::mock_builder()
.plugin(super::init_plugin())
.build(mock_context(noop_assets()))
.unwrap();
// Any other setup code you need
Ok(app)
}
async fn after_each(app: App<MockRuntime>) {
// your clean up code
}
#[tokio::test]
async fn should_return_0_with_no_loaded_models() {
let app = before_each().unwrap();
let window = app.get_window("main").unwrap();
let foo = tauri::test::get_ipc_response::<Vec<String>>(
&window,
tauri::InvokePayload {
cmd: "plugin:my_plugin|foo".into(),
tauri_module: None,
invoke_key: Some(tauri::test::INVOKE_KEY.into()),
callback: tauri::api::ipc::CallbackFn(0),
error: tauri::api::ipc::CallbackFn(1),
inner: serde_json::json!({}),
},
);
assert!(foo.is_ok());
after_each(app).await;
}
}