🧐
Rust で外部依存に対して mock test を書く
目的
外部の crate に依存している場合などで、テストが素直に書けない問題を解決したい。
方針
mockall
という mock test 用のライブラリを使って依存部分を mock してテストを書く。
依存部分を直接 mock することはできなかったので、trait で interface 部分を定義して、そこを mock する形を取る。
手順
mockall を入れる
Cargo.toml
[dependencies]
mockall = "^0.10.2"
interface となる trait を定義する
#[async_trait]
pub trait Printer {
// `&str` の部分を external crate を使って書ける
async fn print(&self, message: &str);
}
interface を mock 化する
#[cfg_attr(test, mockall::automock)]
#[async_trait]
pub trait Printer {
async fn print(&self, &str);
}
trait を使う関数を定義(テストしたい関数)
pub async fn printer_print(printer: &Printer) {
printer.print("hoge")
.await;
}
テストを書く
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_printer_print() {
// `#[cfg_attr(test, mockall::automock)]` で定義すると `MockHoge` の形で呼べるようになる
let mut printer = MockPrinter::new();
// `expect_hoge` で `hoge` 関数を mock できる
printer.expect_print().times(1).return_const(());
printer_print(printer).await
}
}
expect_method
に対してできること
ref: https://docs.rs/mockall/0.10.2/mockall/examples/__mock_MockFoo_Foo/__foo/struct.Expectation.html
サンプル実装
Discussion