0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Rust】mockallでnewをモックする

Last updated at Posted at 2024-05-25

new関数を含む以下のようなトレイトをmockallでモックするのに手間取ったので、その手順をメモする

trait Foo {
    fn new(x: u32) -> Self;
}

手順

コード全体としては以下のようになる。

#[automock]
trait Foo {
    fn new(x: u32) -> Self;
}

#[test]
fn mock_new() {
    let foo = MockFoo::default();
    let foo_ctx = MockFoo::new_context();

    foo_ctx.expect()
        .return_once(|_| foo);
}

手順を分解して説明すると、以下の1. ~ 3.の通りとなる

1. モックの実装

モックの実装手順はいつもの手順と同じ

#[automock]
trait Foo {
    fn new(x: u32) -> Self;
}

2. モックの実体化

モックの実体化は以下のどちらかで行う

// デフォルト値で実体化
let foo = MockFoo::default();
// 引数を与えて実体化
let foo = MockFoo::new(1);
  • 2番目の方法について、いつもの手順で使われる引数なしのnew関数(=MockFoo::new())は実装されず、以下のようなエラーが出るので注意する

      |
    2 |     let foo = MockFoo::new();
      |               ^^^^^^^^^^^^-- an argument of type `u32` is missing
      |
    

3. new関数の期待する呼び出しを定義する

new関数に対応するコンテキスト?を作成して、そのコンテキストで期待する呼び出しを実装するようにする

let foo_ctx = MockFoo::new_context();

// expect()以降のreturn_onceなどについては、return_constなど他のいつものやつも使えるはず
foo_ctx.expect()
    .return_once(|_| foo);
  • いつものようにexpect_new()とするのではなく、単にexpect()とする
  • コンテキスト作成の際に、newを指定している理解(new_context())

一般的な話 : 静的メソッドのモック

上記手順は、静的メソッド(=selfを含まないメソッド)をモックする場合も同様となる

#[automock]
trait Foo {
    fn bar(x: u32) -> u32;
}

#[test]
fn mock_bar() {
    // [関数名]_context()で静的メソッドのコンテキストを作成できる
    let foo_bar_ctx = MockFoo::bar_context();

    foo_bar_ctx.expect()
        .return_const(1u32);
}

+ε : いつものモックと静的メソッドのモックを組み合わせる

いつものモック=静的じゃないメソッドのモック(と思っている)

#[automock]
trait Foo {
    // new関数=静的メソッド
    fn new(x: u32) -> Self;
    // いつものほう
    fn bar(&self) -> u32;
}

#[test]
fn mock_new_bar() {
    // MockFoo::new(1)でもよいと思われる
    let mut foo = MockFoo::default();
    let foo_ctx = MockFoo::new_context();

    // 二つ目の文でfooの所有権が移動するので先にbarの期待する呼び出しを定義する
    // (他にいい方法があるかもしれない、、、)
    foo.expect_bar()
        .return_const(1u32);
    foo_ctx.expect()
        .return_once(|_| foo);
}

参考

  • ドキュメント

  • 関連してそうなソースコード

  • いつものMockFoo::new()が実装されない理由

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?