Rails Minitest ActionView :: Template ::错误:nil的未定义方法:NilClas

时间:2018-01-29 17:31:39

标签: ruby-on-rails ruby testing minitest

试图调试这两天,我只是卡住了。我有一个观点,我正在尝试在rails中测试,当我在浏览器中手动测试时视图工作正常,但我在控制器测试中一直收到此错误:

ActionView::Template::Error: undefined method "name" for nil:NilClass Here is the full error message

这是测试(test / controllers / quotes_controller_test.rb):

  test "should get quotes index as browse" do
    get browse_path
    assert_response :success
  end

它正在打破我渲染此部分的位置(views / quotes / browse.html.erb):

  <% if @recent_quotes.any? %>
    <aside class="recent-quotes browse-quotes col-7">
      <%= render @recent_quotes %>
    </aside>
  <% end %>

部分看起来像这样(views / quotes / _quote.html.erb):

<blockquote id="quote<%= quote.id %> blockquote">
  <small class="text-muted">
    <%= link_to quote.topic.name, artist_path(quote.topic) %>
  </small>
  <p class="mb-0"><%= link_to quote.content, quote_path(quote) %></p>

  <footer class="blockquote-footer">
      <cite title="Source">
        <%= link_to quote.speaker.name, quote.source %>
      </cite>
  </footer>
</blockquote>

控制器操作看起来像这样(controllers / quotes_controller.rb):

  def browse
    @artists = Artist.all
    @recent_quotes  = Quote.all.limit(7)
  end

同样,一切都在浏览器中运行良好,但我无法通过这个简单的测试。如果我删除它通过的部分,所以路线工作正常。我认为测试只是在第一次调用name时查找quote.topic.name方法而没有找到它。

但是它在浏览器中工作,所以我无法弄清楚我在这个测试中做错了什么。

1 个答案:

答案 0 :(得分:1)

抱歉,我的评论声誉不够,所以我会尽力回答。

你的装置里有什么?您是否为所有recent_quotes定义了主题艺术家(带名字)?

Fixtures绕过所有验证,所以即使你在Quote类上有它,你也不会因无效夹具而出现任何错误

在控制器中,您有@recent_quotes = Quote.all.limit(7)。 但是在灯具中,您只能为5个引号定义扬声器和主题。 这部分:

<% 30.times do |n| %>
quote_<%= n %>:
  user: jordan
  content: <%= Faker::Lorem.unique.sentence %>
  speaker_id: <%= rand(1..5) %>
  topic_id: <%= rand(6..10) %>
  created_at: <%= 42.days.ago %>
<% end %>

不起作用,因为1..10中没有带有ID的艺术家。每次当灯具创建实例时,ID都不会从1开始设置,您的艺术家具有503576764之类的ID。所以这部分确实创建了引号,但是它们的topic.name是零,因为主题不存在。

您需要至少手动为7个灯具指定扬声器和话题。或者你需要删除30.times部分 - 我不确定你真的需要它。通常的做法是在灯具中使用2-3个实例。您可以阅读有关灯具here

的更多信息

或者您可以将灯具更改为factories,它会为您提供更加明确和方便的测试记录工作。

还有一件事。在这种情况下,有一个非常简单的调试工具。只需在控制器中添加一些行:

 def browse
    @artists = Artist.all
    @recent_quotes  = Quote.all.limit(7)
    @recent_quotes.map do |quote| 
      # you can add all what you need in this array
      p [quote.valid?, quote.errors, quote.speaker, quote.topic] 
    end
 end

并运行测试。您将在测试输出中看到所有信息。