当我的模拟对象被ActionController要求输入URL时,我在RSpec中遇到了问题。该URL是Mock,而不是正确的资源URL。
我正在运行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 post 方法时。
NotesController正确处理Mock Subject对象,创建!新的 Note 对象。但是当NoteController #Create方法尝试 redirect_to 时,我收到以下错误:
'NotesController中的NoMethodError应该创建注释并重定向到没有javascript的主题' 未定义的方法`spec_mocks_mock_url'用于#&lt; NotesController:0x1034495b8&gt;
现在这是由一些传递ActiveRecord对象的Rails技巧引起的(在我们的例子中是@subject,它不是ActiveRecord而是Mock对象),最终传递给所有传递给所有人的 url_for Rails路由的选项,然后确定URL。
我的问题是如何模拟主题以便传递正确的选项以便我的测试通过。
我尝试传入:controller =&gt; '主题'选项,但没有快乐。
还有其他方法吗?
...谢谢
答案 0 :(得分:2)
查看mock_model
,它由rspec-rails添加,以便更容易模拟ActiveRecord对象。根据{{3}}:
mock_model: Creates a mock object instance for a model_class with common methods stubbed out.
我不确定它是否会照顾url_for
,但值得一试。
更新,2018-06-05 :
mock_model
和stub_model
已被提取到As of rspec 3。
答案 1 :(得分:0)
如果zetetic的想法没有成功,你可以随时说出Subject.new
,然后将to_param
以及你可能需要伪造的其他任何内容用于你的例子。