带有视图测试和嵌套资源的 Rspec 和 Rails

Posted

技术标签:

【中文标题】带有视图测试和嵌套资源的 Rspec 和 Rails【英文标题】:Rspec and Rails with View Tests and Nested Resources 【发布时间】:2012-07-08 00:26:57 【问题描述】:

我正在开发一个 Yahoo Answers 类的应用程序来提高我的 Rails 技能。 到目前为止,我已经设置了两个模型“问题”和“答案”,它们是这样嵌套的:

  resources :questions do
    resources :answers
  end

我已经对控制器、模型和问题的视图进行了测试,但是我在答案的视图和嵌套路由方面遇到了一些问题。我正在使用 Rspec 和 Factory girl。

我有以下测试:

describe "answers/new.html.erb" do
  before(:each) do
    @question = Factory(:valid_question)
    @answer = Factory(:valid_answer)
    assign(:question, @question)
    assign(:answer, stub_model(Answer,
      :text => "MyString",
      :question_id => 1
    ).as_new_record)
  end

  it "renders new answer form" do
    render
    assert_select "form", :action => question_answers_path(@question), :method => "post" do
      assert_select "textarea#answer_text", :name => "answer[text]"
      assert_select "input#answer_question_id", :name => "answer[question_id]"
    end
  end
end

每当我运行测试时,我都会收到以下消息:

  3) answers/new.html.erb renders new answer form
     Failure/Error: render
     ActionView::Template::Error:
       No route matches :controller=>"answers"
     # ./app/views/answers/new.html.erb:6:in `_app_views_answers_new_html_erb__3175854877830910784_6513500'
     # ./spec/views/answers/new.html.erb_spec.rb:16:in `block (2 levels) in <top (required)>'

我尝试过很多事情,比如做

render new_question_answer_path(@question)

但我明白了:

  3) answers/new.html.erb renders new answer form
     Failure/Error: render new_question_answer_path(@question.id)#, :format=>:html
     ActionView::MissingTemplate:
       Missing partial /questions/1/answers/new with :handlers=>[:erb, :builder, :coffee], :formats=>[:html, :text, :js, :css, :ics, :csv, :xml, :rss, :atom, :yaml, :multipart_form, :
url_encoded_form, :json], :locale=>[:en, :en]. Searched in:
         * "/home/juan/rails_projects/answers/app/views"
     # ./spec/views/answers/new.html.erb_spec.rb:16:in `block (2 levels) in <top (required)>'

你能帮我解决这个问题吗?我现在有点不知所措。

【问题讨论】:

【参考方案1】:

我认为你认为错误。可以加吗?

另外,这里有一些关于使用 RSpec 的建议:

您可以将@question@answer 放在一个 let 块中。这是目前的首选方式。查看文档,使用起来相当简单。 您实际上应该使用FactoryGirl.create,而不是Factory()。如果您在 RSpec 配置中包含 Factory::Syntax::Methods,则可以将其缩短为 create。 将测试替身与真实模型混合通常不是一个好主意。您应该将视图与模型隔离开来,或者将它们一直集成在一起——要么将 stub_model 替换为 Answer.build,要么为 @question@answer 使用存根。 FactoryGirl 的 Factory.build_stubbed 基本上是 stub_model 适合视图规格。 视图规格已失宠。我建议在 RSpec 邮件列表中搜索有关人们选择避免​​使用它们的详细信息。我的看法是它们相当脆弱(更改代码时很容易破坏),因为它们依赖于模型和助手。要么他们强迫你大量存根,集成模型,要么编写一个简单的演示者。话虽如此,它们有它们的用途,但它们很少见。更好的选择是在集成中测试这种交互,使用黄瓜、牛排或仅使用 rspec 和水豚。 您的断言是您通常不想在视图规范中测试的示例。您断言存在一些标记,包括表单字段,这本身并不是一个好的测试,因为它告诉您表单在那里,但不是它正在工作。您将获得更好的集成覆盖率。此外,它也不会那么脆弱 - 例如,如果您重命名模型或字段,则无需更改视图规范。

【讨论】:

【参考方案2】:

我遇到了这个问题。如果您仔细查看堆栈跟踪,您会发现您的视图被正确调用,但第 6 行出现错误。

在我的情况下,这是由调用其中一个 rails 路径帮助引起的,例如 answers_path(@question),但它被传递为零。

解决方法是为该实例变量添加一个assign 调用。如果改为使用局部变量,则可以在调用render 时通过:locals 散列传入。

【讨论】:

以上是关于带有视图测试和嵌套资源的 Rspec 和 Rails的主要内容,如果未能解决你的问题,请参考以下文章

资产预编译后,RSpec / Capybara测试不会通过

如何使用rails cucumber,rspec,capybara在视图(dhtml)中测试动态部分?

在某些 RSpec rails 请求示例中测试 HTTP 状态代码,但在其他示例中测试引发异常

rspec 使用 draper Decorator 测试视图

使用 rspec 测试视图 - 渲染视图时帮助文件中未定义的 current_user

是否有RSpec等效的RSpec来做TDD?