クラスダブルの使用
class_double
は、instance_double
の補完として提供されており、与えられたクラスのクラスメソッドを検証する点が異なります。
さらに、具体的なクラスを定義されたダブルで置き換えるための便利なメソッドas_stubbed_const
も提供されています。詳細については、定数の変更を参照してください。
注意: class_double
はモジュールにも使用できます。ただし、モジュールを扱っている場合でも、一般的には「クラスメソッド」と呼ばれるメソッドをclass_double
が検証するため、class_double
の用語を使用することにしました。
背景
次の内容で「lib/user.rb」という名前のファイルがあるとします:
class User
def suspend!
ConsoleNotifier.notify("suspended as")
end
end
次の内容で「lib/console_notifier.rb」という名前のファイルがあるとします:
class ConsoleNotifier
MAX_WIDTH = 80
def self.notify(message)
puts message
end
end
次の内容で「spec/user_spec.rb」という名前のファイルがあるとします:
require 'user'
require 'console_notifier'
RSpec.describe User, '#suspend!' do
it 'notifies the console' do
notifier = class_double("ConsoleNotifier").
as_stubbed_const(:transfer_nested_constants => true)
expect(notifier).to receive(:notify).with("suspended as")
expect(ConsoleNotifier::MAX_WIDTH).to eq(80)
user = User.new
user.suspend!
end
end
既存の定数の置き換え
「rspec spec/user_spec.rb」と実行すると、
すべての例がパスするはずです。
ConsoleNotifier.notify
をsend_notification
に名前変更する
次の内容で「lib/console_notifier.rb」という名前のファイルがあるとします:
class ConsoleNotifier
MAX_WIDTH = 80
def self.send_notification(message)
puts message
end
end
「rspec spec/user_spec.rb」と実行すると、
出力には「1つの例、1つの失敗」と表示されるはずです。
また、出力には「ConsoleNotifierクラスはクラスメソッドを実装していません:」と表示されるはずです。