我有一个关于如何在示例之间共享 rspec-mocks 的问题。我正在用 rspec-mocks 编写一个新的 rails 应用程序3.1.3
。我习惯于使用旧的 (< 2.14 并且如果当前的 rspec 使用情况,我会尝试更新我的知识。
我有一个模型方法:
def self.from_strava(activity_id, race_id, user)
@client ||= Strava::Api::V3::Client.new(access_token: 'abc123')
activity = @client.retrieve_an_activity(activity_id)
result_details = {race_id: race_id, user: user}
result_details[:duration] = activity['moving_time']
result_details[:date] = Date.parse(activity['start_date'])
result_details[:comment] = activity['description']
result_details[:strava_url] = "http://www.strava.com/activities/#{activity_id}"
Result.create!(result_details)
end
这是规格:
describe ".from_strava" do
let(:user) { FactoryGirl.build(:user) }
let(:client) { double(:client) }
let(:json_response) { JSON.parse(File.read('spec/support/strava_response.json')) }
before(:each) do
allow(Strava::Api::V3::Client).to receive(:new) { client }
allow(client).to receive(:retrieve_an_activity) { json_response }
allow(Result).to receive(:create!)
end
it "sets the duration" do
expect(Result).to receive(:create!).with(hash_including(duration: 3635))
Result.from_strava('123', 456, user)
end
it "sets the date" do
expect(Result).to receive(:create!).with(hash_including(date: Date.parse("2014-11-14")))
Result.from_strava('123', 456, user)
end
end
当我自己运行一个测试时它很好,但是当我运行整个describe ".from_strava"
块时它会失败并显示消息
Double :client was originally created in one example but has leaked into another example and can no longer be used. rspec-mocks' doubles are designed to only last for one example, and you need to create a new one in each example you wish to use it for.
我明白它在说什么,但肯定这是对double
2 个示例中使用的 a 的适当使用。毕竟,client
双精度对示例并不重要,它只是我加载预设响应的一种方式。我想我可以使用 WebMock,但这似乎非常低级,并且不能很好地转化为实际编写的代码。毕竟,每个例子我们应该只断言一件事。
我曾想过client
用一个电话来代替双重
allow(Strava::Api::V3::Client).to receive_message_chain(:new, :retrieve_an_activity) { json_response }
但这似乎也不是正确的方法,因为文档指出这 receive_message_chain
应该是代码气味。
因此,如果我不应该使用receive_message_chain
, shared client
double 并且还遵循标准 DRY 原则,那么我应该如何解决这个问题?
我希望对此有一些反馈。
谢谢,戴夫