【问题标题】:Ruby Rails RSpec Local VariablesRuby Rails RSpec 局部变量
【发布时间】:2011-12-21 14:03:50
【问题描述】:

我使用 AJAX 过滤索引操作中的响应列表,但我不确定如何测试它。

index.html.erb:

<h1>Listing traits</h1>
<%= render "partials/filter" %>
<%= link_to 'New Trait', new_trait_path %>
<div id="filter_table">
  <%= render 'list', :traits => @traits %>
</div>

_list.html.erb:

<% if traits.size > 0 %>
<table class="tablesorter">
  <thead>
  <tr>
    <th>Pedigree</th>
    <th>Person</th>
    <th>Phenotype</th>
    <th>Value</th>
    <th>Output order</th>
    <th class="nosort">controls</th>
  </tr>
  </thead>
  <tbody>
<% traits.each do |trait| %>
  <tr>
    <td><%= trait.person.pedigree.name %></td>
    <td><%= trait.person.identifier %></td>
    <td><%= trait.phenotype.name if trait.phenotype %></td>
    <td><%= trait.trait_information %></td>
    <td><%= trait.output_order %></td>
    <td><%= link_to 'Show', trait %></td>
  </tr>
<% end %>
</tbody>
</table>
<% else %>
  <p>No traits for person <%if params[:person] %><%= Person.find(params[:person]).full_identifier %><% end %></p>
<% end %>

index.js.erb

$("#filter_table").replaceWith("<div id=\"filter_table\"><%= escape_javascript(render 'list', :traits => @traits) %></div>")
$(".tablesorter").tablesorter({widgets: ['zebra']});

traits_controller:

 def index
    @traits = Trait.has_pedigree(params[:pedigree_filter]).has_person(params[:person])

    respond_to do |format|
      format.html # index.html.erb
      format.xml  { render :xml => @traits }
      format.js
    end
  end

Rspec 代码:

require 'spec_helper'
describe "traits/index.html.erb" do
  before(:each) do
    @traits = assign(:traits, [
      stub_model(Trait),
      stub_model(Trait)
    ])
  end

  it "renders a list of traits" do
    render
  end
end

Rspec 输出:

失败:

  1) traits/index.html.erb renders a list of traits
     Failure/Error: render
     ActionView::Template::Error:
       undefined method `pedigree' for nil:NilClass
     # ./app/views/traits/_list.html.erb:16:in `block in _app_views_traits__list_html_erb___3395464522456253198_189374900'
     # ./app/views/traits/_list.html.erb:14:in `each'
     # ./app/views/traits/_list.html.erb:14:in `_app_views_traits__list_html_erb___3395464522456253198_189374900'
     # ./app/views/traits/index.html.erb:11:in `_app_views_traits_index_html_erb__2914970758361867957_188338000'
     # ./spec/views/traits/index.html.erb_spec.rb:12:in `block (2 levels) in <top (required)>'

Finished in 0.42509 seconds
1 example, 1 failure

更新:所以上面的代码是错误的,这就是 Rspec 试图告诉我的。我更新了代码以正常工作,现在上面的错误就是我得到的。我不确定如何在使用 assign(:traits, [stub_model(Trait), stub_model(Trait)]) 创建每个 Trait 对象时为其分配 Pedigree 对象。

【问题讨论】:

  • 鉴于上面的代码,_list.html.erb 怎么知道traits 是什么?您能否发布在渲染调用中包含 :locals =&gt; { :traits =&gt; @traits } 时遇到的错误?
  • 你完全正确。我修复了 index.html.erb 中的渲染调用并更新了我得到的错误。

标签: ruby-on-rails ruby rspec render local-variables


【解决方案1】:

问题在于您使用stub_model。在您看来,@traitsstub_model(Trait) 实例的列表。但是,您没有在这些实例上设置人员,因此在第 16 行的 _list.html.erb 中,您尝试在 nil 上调用 #pedigree

index.html.erb_spec.rbbefore 块中尝试以下类似操作:

before(:each) do
  person = stub_model(Person, :pedigree => 'something', :identifier => 'id') # etc.
  @traits = assign(:traits, [
    stub_model(Trait, :person => person),
    stub_model(Trait, :person => person)
  ])
end

还可以查看stub_model documentation

【讨论】:

    猜你喜欢
    • 2016-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-11
    • 1970-01-01
    • 1970-01-01
    • 2018-05-05
    • 2014-01-31
    相关资源
    最近更新 更多