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

时间:2012-07-08 00:26:57

标签: ruby-on-rails rspec views factory-bot nested-resources

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

  resources :questions do
    resources :answers
  end

我已经对控制器,模型和问题的观点进行了测试,但是我对答案的视图和嵌套路线有点麻烦。我正在使用Rspec和Factory女孩。

我有以下测试:

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)>'
你能帮我解决这个问题吗?我现在有点无能为力。

2 个答案:

答案 0 :(得分:8)

我认为错误在你看来。你可以加一下吗?

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

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

答案 1 :(得分:2)

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

在我的情况下,这是由于调用其中一个rails path帮助引起的,类似于answers_path(@question),但是它被传递为nil。

修复是为该实例变量添加assign调用。如果使用局部变量,则可以在调用:locals时通过render哈希传入。