Edited at

Rails minitest キーワード引数を叩くMockの定義方法

@koshi_life です。

Rails 標準のテストフレームワーク minitest にてキーワード付き引数を叩くMockの定義方法でハマったので備忘です。


前提


  • Rails 5.2.3

  • Ruby 2.6.0

  • minitest 5.11.3


検証対象モジュール

比較用に検証対象モジュール内で通常引数、キーワード引数各Mock化する2パターンでテストを書きました。

検証対象モジュールは以下とコード参考。



  • Hoge#countup_normal_args():

    通常引数の @api_client.get , @api_client.update を叩く


  • Hoge#countup_keyword_args():

    キーワード引数の @api_client.get(item_id:),@api_client.update(item_id:, value:) を叩く


hoge.rb

class Hoge

def initialize(api_client)
@api_client = api_client
end

# countupメソッド 通常引数のモジュールを利用する
def countup_normal_args(item_id)
item = @api_client.get(item_id)
new_value = item[:val] + 1
@api_client.update(item_id, new_value)
end

# countupメソッド キーワード引数のモジュールを利用する
def countup_keyword_args(item_id)
item = @api_client.get(item_id: item_id)
new_value = item[:val] + 1
@api_client.update(item_id: item_id, value: new_value)
end
end



テスト

3つのケースを定義しました。詳細はコード参照。


  • 通常引数のメソッドを叩くパターン

  • キーワード引数のメソッドを叩くパターン1

  • キーワード引数のメソッドを叩くパターン2 Block 利用


hoge_test.rb

require 'test_helper'

class HogeTest < ActiveSupport::TestCase
test '#Mock 通常引数のメソッドを叩くパターン' do
item_id = 'id-1'
retval_get = { val: 3 }
args_get = [item_id]

retval_update = true
args_update = [item_id, 4]

api_mock = MiniTest::Mock.new
api_mock.expect(:get, retval_get, args_get)
api_mock.expect(:update, retval_update, args_update)

# 検証したいモジュールを実行します
hoge = Hoge.new(api_mock)
result = hoge.countup_normal_args(item_id)
assert_equal(true, result)

# Mockに送信されたデータを検証します。
api_mock.verify
end

test 'キーワード引数のメソッドを叩くパターン1' do
item_id = 'id-2'
retval_get = { val: 3 }
args_get = [{ item_id: item_id }] # 配列の中にハッシュで定義

retval_update = true
args_update = [{ item_id: item_id, value: 4 }] # 配列の中にハッシュで定義

api_mock = MiniTest::Mock.new
api_mock.expect(:get, retval_get, args_get)
api_mock.expect(:update, retval_update, args_update)

# 検証したいモジュールを実行します
hoge = Hoge.new(api_mock)
result = hoge.countup_keyword_args(item_id)
assert_equal(true, result)

# Mockに送信されたデータを検証します。
api_mock.verify
end

test 'キーワード引数のメソッドを叩くパターン2 Block 利用' do
item_id = 'id-3'
retval_get = { val: 3 }
retval_update = true

api_mock = MiniTest::Mock.new
api_mock.expect(:get, retval_get) do |item_id:|
puts ":get() called args item_id:#{item_id}"
item_id == 'id-3'
end
api_mock.expect(:update, retval_update) do |item_id:, value:|
puts ":update() called args (item_id:#{item_id}, value:#{value})"
item_id == 'id-3' && value == 4
end

# 検証したいモジュールを実行します
hoge = Hoge.new(api_mock)
result = hoge.countup_keyword_args(item_id)
assert_equal(true, result)

# Mockに送信されたデータを検証します。
api_mock.verify
end
end



参考