instance_doubleの使用方法
instance_double
は最も一般的な検証用のダブルです。最初の引数にはクラス名またはオブジェクトを指定し、スタブ化されるメソッドがそのクラスのインスタンスに存在することを検証します。さらに、メッセージを受け取る際には、提供された引数がメソッドのシグネチャに対応しているかどうか(引数の数や許可される/必要なキーワード引数など)も検証します。同じ引数の検証は、with
を使用して引数を制約する場合にも行 われます。
method_missing
で処理されるメソッドについては、動的クラスを参照してください。
背景
次の内容で「app/models/user.rb」という名前のファイルがあるとします。
class User < Struct.new(:notifier)
def suspend!
notifier.notify("suspended as")
end
end
次の内容で「spec/unit_helper.rb」という名前のファイルがあるとします。
$LOAD_PATH.unshift("app/models")
次の内容で「spec/spec_helper.rb」という名前のファイルがあるとします。
require 'unit_helper'
require 'user'
require 'console_notifier'
RSpec.configure do |config|
config.mock_with :rspec do |mocks|
# This option should be set when all dependencies are being loaded
# before a spec run, as is the case in a typical spec helper. It will
# cause any verifying double instantiation for a class that does not
# exist to raise, protecting against incorrectly spelt names.
mocks.verify_doubled_constant_names = true
end
end
次の内容で「spec/unit/user_spec.rb」という名前のファイルがあるとします。
require 'unit_helper'
require 'user'
RSpec.describe User, '#suspend!' do
it 'notifies the console' do
notifier = instance_double("ConsoleNotifier")
expect(notifier).to receive(:notify).with("suspended as")
user = User.new(notifier)
user.suspend!
end
end
独立した状態でスペックがパスする
「rspec spec/unit/user_spec.rb」と実行した場合、すべての例がパスするはずです。
依存関係を読み込み、メソッドを実装した状態でスペックがパスする
次の内容で「app/models/console_notifier.rb」という名前のファイルがあるとします。
class ConsoleNotifier
def notify(msg)
puts message
end
end
「rspec -r./spec/spec_helper spec/unit/user_spec.rb」と実行した場合、すべての例がパスするはずです。
依存関係を読み込み、メソッドが未実装の状態でスペックが失敗する
次の内容で「app/models/console_notifier.rb」という名前のファイルがあるとします。
class ConsoleNotifier
end
「rspec -r./spec/spec_helper spec/unit/user_spec.rb」と実行した場合、出力には「1 example, 1 failure」という文言が含まれるはずです。
また、出力には「ConsoleNotifier class does not implement the instance method:」という文言が含まれるはずです。
依存関係がロードされ、引数の数が間違っている場合にSpecが失敗する
Given "app/models/console_notifier.rb" という名前のファイルが以下の内容であるとき:
class ConsoleNotifier
def notify(msg, color)
puts color + message
end
end
When rspec -r./spec/spec_helper spec/unit/user_spec.rb
を実行すると
Then 出力に "1 example, 1 failure" が含まれているべきであり
And 出力に "Wrong number of arguments." が含まれているべきである。