RSpec の class_double で呼び出しているクラスやメソッドの変更を検出する方法についてまとめます。
テストパターン
クラスもメソッドも存在するケース
require "spec_helper" class Hoge def self.hoge "hoge" end end class HogeUser def initialize(hoge) @hogea = hoge end def use @hogea.hoge end end describe HogeUser do it do hoge = class_double("Hoge") expect(hoge).to receive(:hoge).and_return("aaaaaa") user = HogeUser.new(hoge) expect(user.use).to eq("aaaaaa") end end
- 結果
$ rspec spec/double_exist_method_spec.rb . Finished in 0.0056 seconds (files took 0.09756 seconds to load) 1 example, 0 failures
mocks.verify_doubled_constant_names = false の場合
- spec_helper.rb
# 略 config.mock_with :rspec do |mocks| # ※設定を省略した場合はデフォルトで false になります mocks.verify_doubled_constant_names = false end # 略
class_double でクラスが存在しないケース
require "spec_helper" # class Hoge # def self.hoge # "hoge" # end # end class HogeUser def initialize(hoge) @hogea = hoge end def use @hogea.hoge end end describe HogeUser do it do hoge = class_double("Hoge") expect(hoge).to receive(:hoge).and_return("aaaaaa") user = HogeUser.new(hoge) expect(user.use).to eq("aaaaaa") end end
- 結果
正常終了してしまいます。
モック対象の変更やタイポをテストで検出することができません。
$ rspec spec/double_not_exist_class_spec.rb . Finished in 0.00536 seconds (files took 0.12313 seconds to load) 1 example, 0 failures
class_double でメソッドが存在しないケース
require "spec_helper" class Hoge # def self.hoge # "hoge" # end end class HogeUser def initialize(hoge) @hogea = hoge end def use @hogea.hoge end end describe HogeUser do it do hoge = class_double("Hoge") expect(hoge).to receive(:hoge).and_return("aaaaaa") user = HogeUser.new(hoge) expect(user.use).to eq("aaaaaa") end end
- 結果
メソッドが存在しないとエラーになります。
メソッド名の変更をエラーとして検出できます。
$ rspec spec/double_not_exist_class_spec.rb F Failures: 1) HogeUser Failure/Error: hoge = class_double("Hoge") "Hoge" is not a defined constant. Perhaps you misspelt it? Disable check with `verify_doubled_constant_names` configuration option. # ./spec/double_not_exist_class_spec.rb:21:in `block (2 levels) in <top (required)>' Finished in 0.00054 seconds (files took 0.10972 seconds to load) 1 example, 1 failure Failed examples: rspec ./spec/double_not_exist_class_spec.rb:20 # HogeUser
mocks.verify_doubled_constant_names = true の場合
- spec_helper.rb
# 略 config.mock_with :rspec do |mocks| mocks.verify_doubled_constant_names = true end # 略
class_double でクラスが存在しないケース
ソースコードは verify_doubled_constant_names = false
のケースと同じ
- 結果
クラスが存在しないとエラーになります。
クラス名の変更をエラーとして検出できます。
$ rspec spec/double_not_exist_class_spec.rb Failures: 1) HogeUser Failure/Error: hoge = class_double("Hoge") "Hoge" is not a defined constant. Perhaps you misspelt it? Disable check with `verify_doubled_constant_names` configuration option. # ./spec/double_not_exist_class_spec.rb:21:in `block (2 levels) in <top (required)>' Finished in 0.00054 seconds (files took 0.10972 seconds to load) 1 example, 1 failure Failed examples:
class_double でメソッドが存在しないケース
- ソースコードは
mocks.verify_doubled_constant_names = false
の例と同じなので省略 - 実行結果は
mocks.verify_doubled_constant_names = false
の例と同じなので省略