我是rspec的新手,我遇到了一些问题。有人能帮助我吗?
我有一个控制器操作负责停用用户。我试图用rspec测试覆盖它,但结果并不是我正在等待的。
控制器:
def deactivate
@user = User.find(params[:id])
if !@user.nil?
@user.update_attribute(:active, false)
redirect_to users_url
end
end
控制器规格
describe "PUT #deactivate" do
describe "with valid parameters" do
before (:each) do
@user = mock_model(User, :id => 100, :login => "login", :password => "password123",
:email => "email@gmail.com", :active => true)
User.should_receive(:find).with("100").and_return(@user)
end
it "should deactivate an user" do
@user.stub!(:update_attribute).with(:active, false).and_return(true)
put :deactivate, :id => "100"
@user.active.should eq false
end
end
end
测试结果:
1) UsersController PUT #deactivate with valid parameters should deactivate an user
Failure/Error: @user.active.should eq false
expected: false
got: true
(compared using ==)
所以,我不明白为什么当属性应该为false时,active属性仍为true。有什么想法吗?
谢谢!
答案 0 :(得分:1)
您似乎不必要地存在update_attribute方法。尝试删除该行,看看会发生什么。
答案 1 :(得分:0)
您的期望是"错误"。
让我们看看执行规范it "should deactivate an user"
时会发生什么:
@user.stub!(:update_attribute).with(:active, false).and_return(true)
修改现有的模拟模型,因此它具有update_attribute
,当使用参数:active
和false
调用时
true
User
对象不同,将不会执行任何其他操作)put :deactivate, :id => "100"
调用控制器中的真实deactivate
User.find
。但是你已经嘲笑了那个类方法,它将返回模拟对象@user
,而不是用id
搜索实际用户。@user.update_attribute
。但是由于上面的步骤3,@user
这里也是模拟对象。其update_attributes
方法是第1步中的方法。正如我们上面所见,它将返回true,跟踪此调用发生的情况,不执行任何其他操作。这意味着它将不更改@user
的{{1}}属性,以便保留active
。调用true
时更改active
是实际update_attribute
类的对象的功能,但在运行规范时没有这样的对象发挥作用。由于此功能是继承自User
,因此您无需对其进行测试。而是仅测试模拟对象已收到ActiveRecord
:
update_attribute
(我在此基于how it's done with the newer expect
syntax猜测旧的 it "should deactivate an user" do
@user.stub!(:update_attribute).with(:active, false).and_return(true)
put :deactivate, :id => "100"
@user.should have_received(:update_attribute).with(:active, false)
end
语法。)
如果做想要测试控制器与实际should
实现的组合功能,请不要模拟User
或其对象。而是使用request spec从浏览器角度进行测试。 (这可能是有意义的另外,即使你只想要控制器(模拟模型)和仅模型(可能不会需要双打,除非可能是其他型号)。
答案 2 :(得分:0)
我很长时间都在寻找这个问题,无论您使用let
还是build
update_column
始终都可以使用
答案 3 :(得分:-1)
你可以试试这个:
describe "should deactivate an user" do
before do
@user.stub!(:update_attribute).with(:active, false).and_return(true)
put :deactivate, :id => "100"
end
it { @user.active.should eq false }
end
答案 4 :(得分:-2)
当你模仿对update_attribute
的调用时,模型将如何改变?
如果你是初学者:不要使用存根和嘲笑!
首先获得测试的一般知识,然后将您的知识扩展到模拟和存根。