2012-03-31 26 views
4

我有以下規格提供給測試控制器方法:Rspec的存根不起作用

context "#create" do 
    it "should redirect when model is valid" do 
    User.stub!(:valid?).and_return(true) 
    post :create, :user => FactoryGirl.attributes_for(:user) 
    response.should redirect_to("/") 
    end 
    it "should render new template when model is invalid" do 
    User.stub!(:valid?).and_return(false) 
    post :create, :user => FactoryGirl.attributes_for(:user) 
    response.should render_template(:new) 
    end 
end 

和控制器本身:

def create 
    @user = User.new(params[:user]) 
    if @user.save 
    redirect_to "/", :notice => "User created" 
    else 
    render "new" 
    end 
end 

差不多簡單的代碼,但不知何故stub!方法少了點真的存根,所以第二個規格不符合expecting <"new"> but rendering with <"">。它只是重定向,如果valid?返回true。

我對Rails的世界很陌生。我錯過了什麼?謝謝。

回答

4

保存對象時,Rails在類的實例上調用valid?。但是你在類本身上鑿了valid?。這是行不通的。

您想要在此處執行的是存儲的用戶的實例上的存根save,例如,

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

@user = User.new#@user現在是一個模擬對象

@user.save#模擬對象返回true

對於其他例如:

User.stub(:new) { mock_model(User, :save => false) }

@user = User.new#再次, @user是一個模擬

@user.save#mock對象返回false

+0

OMG感謝比如小費!這是問題所在。雖然我認爲將低級別的方法(比如'valid?')存檔會更好。通過這種方式,我可以在不破壞功能和測試的情況下,將'save'重構爲'build'&'create'。當然,這種情況並非如此。現在我已經通過將存根附加到用戶User.any_instance.stub(:valid?)和and_return(true)'的所有實例來解決它。但是你的提示與實例和課程是我一般錯過的。 – paulus 2012-03-31 13:27:04

+0

至於保存「有效嗎?」而不是「保存」,我認爲是完全相反的:)你關於重構的觀點是一個很好的觀點,但是我們可以把它轉向正確 - 如果ActiveRecord被重構,並且「保存'不再調用'有效?'在引擎蓋下?現在你的測試會因爲你不能控制的庫的內部實現而中斷。 – zetetic 2012-03-31 23:58:53

+0

那麼我們很難在開發/測試中測試它之前切換ActiveRecord,不是嗎? :)如果我們將在開發/測試中,那麼它將是顯而易見的,因爲測試將從這一點失敗。所以我們總是可以通過更新日誌或其他東西來找出原因。從我的角度來看,很可能應用程序類將被重構而不是核心類。 – paulus 2012-04-01 06:57:22