メインコンテンツまでスキップ

クラスダブルの使用

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.notifysend_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クラスはクラスメソッドを実装していません:」と表示されるはずです。