1
0

More than 3 years have passed since last update.

mockeryのOn()にはTimes()を指定しよう

Posted at

TL;DR

https://github.com/vektra/mockery のmock指定時の注意点。

  1. 同じ引数
  2. 返り値が場合によって異なる

の条件を満たすmockを使いまわす場合は On() のメソッドチェーンで Times() をつける。
それが難しければ t.Run のなかで new すること。

回数を指定しない場合 On() の上書きが効かないので、最初にセットされた Return() を返し続けることになる。

func TestHoge(t *testing.T) {
    mockFoo := new(mocks.Foo)
    mockBar := new(mocks.Bar)

    t.Run("test - first", func(t *testing.T) {
        mockFoo.On("FuncA", mock.Anything).Return(1)
        mockBar.On("FuncB", 1).Return(1)

        // テストコード
    })
    t.Run("test - second", func(t *testing.T) {
        mockFoo.On("FuncA", mock.Anything).Return(2)
        mockBar.On("FuncB", 2).Return(2)

        // テストコード
    })
}

test - firsttest - second の順にテストが流れると想定する。)
上記のようなテストがあったとき、mockが返す値は以下のようになる。

mockFoo.FuncA mockBar.FuncB
test - first 1 1
test - second 1 2

原因は、モックが 同じ引数On() を上書きできないため。
Return() 指定時にあらかじめ回数を指定されない限り、最初にセットされた Return() をずっと返し続ける様子。

どちらのテスト内でも引数 mock.Anything を渡されている FuncAtest - second の中でも1 を返している( test - first でセットされたため)が、
t.Run() の中で毎回違う引数を渡されている FuncB はそれぞれ期待の値でモックできている。

対応策

呼び出し回数を指定する。 Times() など。
回数を指定すると、その回数に到達したときに自動的にモックを解除してくれる。

ちなみに、指定の回数 < 実際に呼ばれた回数になるとPanicになる。
mock.AssertExpectations(t) を指定しておくと、
実際に呼ばれた回数 < 指定の回数だったときにもエラーにできる。
これらもテストとして有効利用できるかも。

  • Once()
    • 1回だけ呼ぶ
  • Twice()
    • 2回だけ呼ぶ
  • Times(i int)
    • i で指定した回数だけ呼ぶ。3回以上指定したい時はこれ
func TestHoge(t *testing.T) {
    mockFoo := new(mocks.Foo)
    mockBar := new(mocks.Bar)

    t.Run("test - first", func(t *testing.T) {
        mockFoo.On("FuncA", mock.Anything).Return(1).Once()  // 1回
        mockBar.On("FuncB", 1).Return(1).Once()  // 1回
    })
    t.Run("test - second", func(t *testing.T) {
        mockFoo.On("FuncA", mock.Anything).Return(2).Twice()  // 2回
        mockBar.On("FuncB", 2).Return(2).Times(3)  // 3回
    })
}

どうしても Times() の指定が難しい場合は、 t.Run() の中で毎回mockを作り直したほうが事故を防げる。

1
0
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
1
0