【发布时间】:2015-06-11 10:09:52
【问题描述】:
我正在为我的一个服务对象编写单元测试。在这种特殊情况下,我需要使用事务来确保数据完整性。因此,我有一个像这样的简单代码:
class CreateUser
def save
user_klass.db.transaction do
user = user_klass.create(name: name, email: email)
another_model_klass.find_or_create(user_id: user.id, foo: 'foo')
end
end
end
我使用 Sequel 作为我的 ORM。但是,这个问题的重点实际上是如何测试这段代码。我已经成功地使用了 mocks 和 stubs,但这是我第一次必须使用涉及块的东西来存根。
起初我有一个像这样的幼稚规范:
describe CreateUser do
describe "#save" do
let(:user) { instance_double("User", id: 1) }
let(:user_klass) { double("Class:User", create: user) }
let(:another_model_klass) { double("Class:AnotherModel") }
let(:name) { 'Test User' }
let(:email) { 'test@test.com' }
let(:foo) { 'foo' }
let(:params) { { name: name, email: email, foo: foo } }
let!(:form) { CreateUser.new(params, user_klass, another_model_klass) }
before do
allow(another_model_klass).to receive(:find_or_create)
end
it "sends create message to the user_klass" do
expect(user_klass).to receive(:create).with({ name: name, email: email}).and_return(user)
form.save
end
it "sends find_or_create message to another_model_klass" do
expect(another_model_klass).to receive(:find_or_create).with(user_id: user.id, foo: foo)
form.save
end
end
end
这给出了一个错误:
Double "Class:User" received unexpected message :db with (no args)
但如果我添加以下内容:
allow(user_klass).to receive_message_chain(:db, :transaction)
它会将事务块的内容存根,但它仍然会失败。
如何在我的规范中设定期望:
- 期望交易被使用
- 期望创建消息发送到 user_klass
- 期待 find_or_create 消息发送到 another_model_klass
【问题讨论】:
标签: ruby rspec rspec-rails sequel rspec3