我无法弄清楚为什么这个RSpec测试失败了。有什么建议?我是FactoryGirl,RSpec和TDD的新手。
def update
@vendor = current_user.vendors.find(params[:id])
if @vendor.update_attributes(params[:vendor])
redirect_to vendor_path(@vendor)
else
render 'edit'
end
end
require 'spec_helper'
describe VendorsController do
login_user
before :each do
@user = subject.current_user
@vendor = FactoryGirl.create(:vendor, :user => @user)
end
[...]
describe 'POST update' do
def do_update
post :update, :id => @vendor.id, :vendor => FactoryGirl.attributes_for(:vendor)
end
[...]
it 'should update a given vendor' do
do_update
@vendor.should_receive(:update_attributes).with(FactoryGirl.attributes_for(:vendor))
end
end
end
FactoryGirl.define do
factory :vendor do
name 'Widget Vendor'
user
end
end
Failures:
1) VendorsController POST update should update a given vendor
Failure/Error: @vendor.should_receive(:update_attributes).with(FactoryGirl.attributes_for(:vendor))
(#<Vendor:0x007faeb75e77d0>).update_attributes({:name=>"Widget Vendor"})
expected: 1 time
received: 0 times
# ./spec/controllers/vendors_controller_spec.rb:108:in `block (3 levels) in <top (required)>'
我现在离我更近了。我将测试更改为以下内容:
it 'should update a given vendor' do
Vendor.any_instance.should_receive(:update_attributes).with(FactoryGirl.attributes_for(:vendor))
do_update
end
新错误是:
Failures:
1) VendorsController POST update should update a given vendor
Failure/Error: post :update, :id => @vendor.id, :vendor => FactoryGirl.attributes_for(:vendor)
#<Vendor:0x007ff30d765900> received :update_attributes with unexpected arguments
expected: ({:name=>"Widget Vendor"})
got: ({"name"=>"Widget Vendor"})
# ./app/controllers/vendors_controller.rb:33:in `update'
# ./spec/controllers/vendors_controller_spec.rb:98:in `do_update'
# ./spec/controllers/vendors_controller_spec.rb:108:in `block (3 levels) in <top (required)>'
嗯,这很有效。不过,必须有一种更好的方法:
Vendor.any_instance.should_receive(:update_attributes).with(JSON.parse(FactoryGirl.attributes_for(:vendor).to_json)).and_return(true)
答案 0 :(得分:2)
我认为你做错了。
规范中的@vendor对象是控制器中的另一个对象,因此它不会接收“update_attributes”方法。
你可以尝试这个(可能是rspec 2.5+):
Vendor.any_instance.should_receive(:update_attributes).with(FactoryGirl.attributes_for(:vendor))
或者您可以检查对象属性是否已更改:
expect{
do_update
}.to change(...)
答案 1 :(得分:1)
我认为您需要在发布请求之前设定您的期望;否则,当它达到您的期望时,该对象已被设置。请在do_update
行之后移动should_receive
:
it 'should update a given vendor' do
@vendor.should_receive(:update_attributes).with(FactoryGirl.attributes_for(:vendor))
do_update
end
答案 2 :(得分:0)
您可以在rails中使用Hash stringify键方法:
Vendor.any_instance.should_receive(:update_attributes).with(FactoryGirl.attributes_for(:vendor).stringify_keys)