使用对象替身
object_double
可用于从现有的“模板”对象创建替身,并验证替身上的任何存根方法也存在于模板上。对于易于构建但可能产生深远副作用(例如与数据库或外部 API 通信)的对象,这很有用。在这种情况下,使用替身而不是真实对象可以让你专注于对象接口的通信模式,而不用担心意外导致副作用。object_double
还可用于验证使用 method_missing
定义的对象上的方法,而这在 instance_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
当我运行 rspec spec/user_spec.rb
时
那么示例应该全部通过。
对常量对象进行替身
给定一个名为“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
当我运行 rspec spec/email_spec.rb
时
那么示例应该全部通过。