2010-04-19 48 views
0

我编写以下规格:故障使用RSpec与方法

 
    it "should call user.invite_friend" do 

    user = mock_model(User, :id => 1) 
    other_user = mock_model(User, :id => 2) 
    User.stub!(:find).with(user.id).and_return(user) 
    User.stub!(:find).with(other_user.id).and_return(other_user) 
    user.should_receive(:invite_friend).with(other_user) 

    post :invite, { :id => other_user.id }, {:user_id => user.id} 

    end 

但我发现了以下错误,当我运行规范

 
NoMethodError in 'UsersController POST invite should call user.invite_friend' 
undefined method `find' for # Class:0x86d6918 
app/controllers/users_controller.rb:144:in `invite' 
./spec/controllers/users_controller_spec.rb:13: 

有什么错误?没有.with它工作得很好,但我希望stub方法的不同参数有不同的返回值。以下控制器的操作可能是相关的:

 
    def invite 
    me.invite_friend(User.find params[:id]) 
    respond_to do |format| 
     format.html { redirect_to user_path(params[:id]) } 
    end 
    end 
    def me 
    User.find(session[:user_id]) 
    end 

回答

1

错误的产生是因为存根被“用完”的第一次调用find。第二个find不会被截断,所以你得到了NoMethodError。

有人可以纠正我,如果我错了,但.with出现,当你把它不止一次地对存根一个奇怪的效果。 Rspec似乎将相同参数类型的每个消息与单个存根关联。但另一个参数类型有效地创建了一个不同的存根。所以你的情况,你可以通过调用第二find用细绳修复:

User.stub!(:find).with(other_user.id.to_s).and_return(other_user)

这是你的幸运年,因为实际上控制器期待在params哈希的字符串。

这不回答这个更大的问题:我怎么存根多种方法使用相同的参数类型调用的参数?根据我的经验,你不能那样做。

当然你也可以通过在所有不指定参数避开它。在你的情况下,我会说测试find本身与你的控制器不相关 - 实际上,你正在测试ActiveRecord是否可以对主键进行数据库查询,而主键已经过很好的测试。所以,如果你需要的是在响应存根find正确的顺序,你可以这样做:

User.stub!(:find).and_return(user,other_user)

+0

“这并没有回答这个更大的问题:我怎么存根多种方法与参数调用根据我的经验,你不能那样做。“存根方法可以接收参数为参数的块,并且可以根据该参数的值返回不同的对象。 – arieljuod 2017-10-19 22:00:07