2010-05-14 98 views
1

當我的模擬對象被ActionController詢問URL時,RSpec出現問題。該URL是模擬的而不是正確的資源URL。RSpec在Rails中嘲諷嵌套模型 - ActionController問題

我運行RSpec的1.3.0和Rails 2.3.5

基本上我有兩個型號。主題有多個音符的地方。

class Subject < ActiveRecord::Base 
    validates_presence_of :title 
    has_many :notes 
end 

class Note < ActiveRecord::Base 
    validates_presence_of :title 
    belongs_to :subject 
end 

的routes.rb文件嵌套這兩個資源,例如:

ActionController::Routing::Routes.draw do |map| 
    map.resources :subjects, :has_many => :notes 
end 

NotesController.rb文件看起來像這樣:

class NotesController < ApplicationController 
    # POST /notes 
    # POST /notes.xml 
    def create 
    @subject = Subject.find(params[:subject_id]) 
    @note = @subject.notes.create!(params[:note]) 

    respond_to do |format| 
     format.html { redirect_to(@subject) } 
    end 
    end 
end 

最後,這是我的RSpec規範應該簡單地將我的模擬對象發佈到NotesController並執行......它可以:

it "should create note and redirect to subject without javascript" do 
    # usual rails controller test setup here 
    subject = mock(Subject) 
    Subject.stub(:find).and_return(subject) 

    notes_proxy = mock('association proxy', { "create!" => Note.new }) 
    subject.stub(:notes).and_return(notes_proxy) 
    post :create, :subject_id => subject, :note => { :title => 'note title', :body => 'note body' } 
end 

的問題是,當RSpec的發佈方法被調用。

NotesController正確處理Mock Subject對象,並創建注意對象。然而,當NoteController#創建方法試圖redirect_to的我得到以下錯誤:

NoMethodError in 'NotesController should create note and redirect to subject without javascript' undefined method `spec_mocks_mock_url' for #<NotesController:0x1034495b8>

現在,這是一個有點掛羊頭賣狗肉的Rails是通過一個ActiveRecord對象(@subject,在我們的情況下,造成ISN 't ActiveRecord,但是一個Mock對象),最終到url_for誰將所有選項傳遞給Rails路由,然後確定URL。

我的問題是我如何模擬主題,以便通過正確的選項,以便我的測試通過。

我試過傳遞:controller =>'subjects'選項但沒有喜悅。

有沒有其他方式做到這一點?

謝謝...

回答

2

看一看mock_model,這是由RSpec的護欄添加,使其更容易嘲笑ActiveRecord對象。按照api docs

mock_model: Creates a mock object instance for a model_class with common methods stubbed out.

我不知道,如果它需要照顧url_for,但它是值得一試。

+0

奇妙的是,這工作得很好。我一直在解決問題幾個小時,並解決了其他問題,但一直有點失明。非常感謝。 – emson 2010-05-14 21:28:32

0

如果zetetic的想法不能解決,你總是可以說Subject.new,然後將to_param和其他任何你可能需要的東西僞裝成你的例子。