2011-05-16 130 views
8

我對使用rspec生成的腳手架控制器規格發生了些什麼感到困惑。這似乎是有道理的,直到我給我的應用程序添加授權,現在我需要更新我的測試。這是怎麼回事:rspec stub(:new).with ...?

MyClass.stub(:new).with('these' => 'params') { mock_my_class(:save => true) } 

在我控制我創造了新的記錄(它需要CURRENT_USER ID是有效的),當合並散列成PARAMS。 MyClass.new(PARAMS [:my_class] .merge(:USER_ID => current_user.id))

測試失敗

expected: ({"these"=>"params"}) 
got: ({"these"=>"params", "user_id"=>315}) 

這是有道理的,因爲新的方法接收測試失敗PARAMS它沒」沒想到。它預計會收到{'these'=>'params'}但它實際上收到{'these'=>'params','user_id'=> 1234}

所以我的自然反應是調整測試,因爲新方法應該收到{'these'=>'params','user_id'=> 1234}並返回模擬對象。

所以我添加到測試如下:

MyClass.stub(:new).with({'these' => 'params', 'user_id' => @user.id}) { mock_my_class(:save => true) } 

這裏就是我打通一個循環拋出。測試的輸出如下:

expected: ({"these"=>"params", "user_id"=>298}) 
got: ({"these"=>"params"}) 

看起來好像是一個成功的測試魔法般地迴避我。我確信這些結果是有邏輯的原因的,但我似乎無法弄清楚。

任何幫助? :)

注:

RSpec的網站說以下內容:

Account.should_receive(:find).with("37").and_return(account) 

Account.stub!(:find).and_return(account) 

這是很容易跟着它只是似乎很奇怪的產生支架不會包含這些方法(除非我拙劣的東西是可能的(:)


通行證

login_admin 
describe "with valid params" do 
    it "assigns a newly created forum_sub_topic as @forum_sub_topic" do 
    ForumSubTopic.stub(:new) { mock_forum_sub_topic(:save => true) } 
    ForumSubTopic.should_receive(:new).with({"these"=>"params", "user_id"=> @admin.id}) #PASS! 
    post :create, :forum_sub_topic => {'these' => 'params'} 
    assigns(:forum_sub_topic).should be(mock_forum_sub_topic) #PASS! 
    end 
end 

失敗

login_admin 
describe "with valid params" do 
    it "assigns a newly created forum_sub_topic as @forum_sub_topic" do 
    ForumSubTopic.stub(:new).with({'these' => 'params', 'user_id' => @user.id}) { mock_forum_sub_topic(:save => true) } 
    post :create, :forum_sub_topic => {'these' => 'params'} 
    assigns(:forum_sub_topic).should be(mock_forum_sub_topic) 
    end 
end 
+0

很高興看到您的rspec代碼的完整代碼,而不僅僅是新的stub代碼。我經常發現我忘記了所有的模型行爲(因爲我們只是測試控制器的行爲是否正確,假設模型假定工作正常)。 – jaydel 2011-05-16 12:29:48

+0

我增加了更多細節。這是唯一失敗的例子。 – 2011-05-16 14:47:15

回答

4

「永遠不要相信一個癮君子」,正如俗話所說。人們也可以說,「永遠不要相信腳手架」。

好的,這有點太苛刻了。腳手架盡力找出哪些參數適用於您生成的模型/控制器,但它不知道嵌套資源(這是我假設您使用的),所以它不會生成user_id參數散列。補充一點:

post :create, :forum_sub_topic => {:user_id=>@user.id} 

these_params關鍵是作爲一個例子產生的 - 將其刪除,並添加任何參數都需要控制器創建MyClass

關於with選項:

MyClass.stub(:new) {mock_model(MyClass,:save=>true)} 

然後MyClass的將任何new消息與模擬響應:stubshould_receive如果你這樣做只會存根指出,符合規定條件的,即消息。如果,另一方面,你這樣做:

MyClass.stub(:new).with({:bogus=>37}) {mock_model(MyClass,:save=>true)} 

然後MyClass的將只有new時也接收{:bogus=>37}作爲參數做出迴應。

+0

這非常有幫助。謝謝。有一件事是,user_id沒有通過生產中的參數傳遞,所以測試不能準確地模擬行爲。我不確定這是否重要。 – 2011-05-18 17:37:24