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

オブジェクトのダブルの使用

object_doubleは、既存の「テンプレート」オブジェクトからダブルを作成するために使用されます。このダブルでは、ダブル上でスタブ化されたメソッドがテンプレート上にも存在することを確認します。これは、データベースや外部APIとの通信などの広範な副作用を持つ可能性があるオブジェクトに便利です。この場合、本物のオブジェクトではなくダブルを使用することで、オブジェクトのインターフェースの通信パターンに焦点を当てることができ、副作用を誤って引き起こす心配をする必要がありません。また、オブジェクトのmethod_missingを使用して定義されたメソッドを検証するためにも、instance_doubleでは不可能なため、object_doubleを使用することができます。

さらに、object_doubleは、以下に示すように特定の定数値と組み合わせて使用することもできます。これは、シングルトンオブジェクトを扱う場合など、ニッチな状況に使用されます。

既存のオブジェクトのダブル化

次の内容で「spec/user_spec.rb」という名前のファイルがあるとします。

class User
# Don't want to accidentally trigger this!
def save; sleep 100; end
end

def save_user(user)
"saved!" if user.save
end

RSpec.describe '#save_user' do
it 'renders message on success' do
user = object_double(User.new, :save => true)
expect(save_user(user)).to eq("saved!")
end
end

When rspec spec/user_spec.rbを実行すると

Then すべての例がパスするはずです。

定数オブジェクトのダブル化

次の内容で「spec/email_spec.rb」という名前のファイルがあるとします。

require 'logger'

module MyApp
LOGGER = Logger.new("myapp")
end

class Email
def self.send_to(recipient)
MyApp::LOGGER.info("Sent to #{recipient}")
# other emailing logic
end
end

RSpec.describe Email do
it 'logs a message when sending' do
logger = object_double("MyApp::LOGGER", :info => nil).as_stubbed_const
Email.send_to('hello@foo.com')
expect(logger).to have_received(:info).with("Sent to hello@foo.com")
end
end

When rspec spec/email_spec.rbを実行すると

Then すべての例がパスするはずです。