2011-05-09 62 views
1

我是rspec和inherited_resources的新手。我有一個簡單的資源,聯繫人,它有一個名稱字段。控制器沒有特殊的功能。Rspec與inherited_resources重定向,而不是渲染失敗更新

class ContactsController < InheritedResources::Base 
    actions :all, :except => [:show] 
end 

我寫了使用mock_model創建和索引的規格很好。但是,在更新時使用mock_model時,它在放置時找不到聯繫人。所以,我轉而使用真正的模型:

describe "PUT update" do 
let(:contact) { Contact.create(:name => "test 1") } 

it "edits the contact" do 
    contact.name = "#{contact.name}-edited" 
end 
context "when the contact updates successfully" do 
    before do 
    contact.stub(:save).and_return(true) 
    end 
    it "redirects to the Contacts index" do 
    put :update, :id => contact.id, :contact => contact 
    #assigns[:contact].name = "test 1 - edited" 
    response.should redirect_to(:action => "index") 
    end 
end 

context "when the contact fails to save" do 
    before do 
    contact.stub(:save).and_return(false) 
    contact.stub(:update_attributes).and_return(false) 
    contact.stub(:errors).and_return(:errors => { :anything => "anything" }) 
    end 
    it "renders the edit template" do 
    put :update, :id => contact.id, :contact => contact 
    response.should render_template :edit 
    end 
end 
end 

我得到以下錯誤:

Failures: 

    1) ContactsController PUT update when the contact fails to save renders the edit template 
    Failure/Error: response.should render_template :edit 
    Expected block to return true value. 
    # ./spec/controllers/contacts_controller_spec.rb:82:in `block (4 levels) in <top (required)>' 

當我檢查STATUS_CODE,這是一個302重定向到/聯繫人/:ID。

我在做什麼錯?

回答

3

當人們開始在控制器測試中使用mock時,這是一個非常常見的問題。你在規範本地的對象上存根方法。當您使用put訪問控制器時,InheritedResources調用Contact.find(params[:id])並獲取其自己的對象,而不是您想要的對象。

您的規格失敗,因爲update_attributes運行正常且重定向回到對象的show頁面。

此問題的一般修補程序也是模擬您的模型上的find方法,以便它返回您的廢除對象而不是另一個。

Contact.should_receive(:find).and_return(contact) 
contact.should_receive(:update_attributes).and_return(false) 
put :update, :id => contact.id, # etc. 
+0

這一切都變得清晰。謝謝! – rmw 2011-05-11 16:37:48