【问题标题】:RSpec mocking a nested model in Rails - ActionController problemRSpec 在 Rails 中模拟嵌套模型 - ActionController 问题
【发布时间】:2010-05-14 17:41:16
【问题描述】:

当 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 的主题' #<0x1034495b8>

    标签: ruby-on-rails mocking rspec


    【解决方案1】:

    看看mock_model,它是由 rspec-rails 添加的,可以更轻松地模拟 ActiveRecord 对象。根据api docs

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

    我不确定它是否能处理url_for,但值得一试。


    2018 年 6 月 5 日更新

    As of rspec 3:

    mock_modelstub_model 已被提取到rspec-activemodel-mocks gem

    【讨论】:

    • 太棒了,效果很好。几个小时以来,我一直在为这个问题头疼,并解决了其他问题,但有点眼花缭乱。非常感谢。
    【解决方案2】:

    如果 zetetic 的想法行不通,您总是可以说 Subject.new,然后删除 to_param 以及您可能需要为您的示例伪造的任何其他内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多