2010-04-19 46 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