如何使用rspec 3.3测试每个对象的部分渲染?

时间:2015-10-14 07:43:59

标签: ruby-on-rails ruby rspec render

以下是我在documentation中找到的内容:

require "rails_helper"

RSpec.describe "widgets/index" do
  it "displays all the widgets" do
    assign(:widgets, [
      Widget.create!(:name => "slicer"),
      Widget.create!(:name => "dicer")
    ])

    render

    expect(rendered).to match /slicer/
    expect(rendered).to match /dicer/
  end
end

但如果我在视图中写这个没有区别

<%= render @widgets %>

或者

<% @widgets.each do |widget| %>
  <p><%= widget.name %></p>
<% end %>

然后我决定尝试这个(来源相同):

require "rails_helper"

RSpec.describe "rendering locals in a partial" do
  it "displays the widget" do
    widget = Widget.create!(:name => "slicer")

    render "widgets/widget", :widget => widget

    expect(rendered).to match /slicer/
  end
end

但它仅适用于渲染一个对象,即

<%= render @product %>

而不是

<%= render @products %>

那么如何测试我的窗口小部件列表是否为每个窗口小部件呈现部分?

1 个答案:

答案 0 :(得分:0)

好吧,因为rendered字符串只返回视图实际呈现的内容(正如人们所预料的那样),所以行为符合预期。

expect(rendered).to match /slicer/只是声明渲染的字符串包含单词slicer,而不是部分视图是否实际呈现。

解决此问题的一种快捷方法是将rendered字符串与仅部分视图的内容匹配,如下所示:

require "rails_helper"

RSpec.describe "widgets/index" do
  it "displays all the widgets" do
    assign(:widgets, [
      Widget.create!({ name: "slicer", body: "this is the slicer body"}),
      Widget.create!({ name: "dicer", body: "this is the dicer body"})
    ])

    render

    expect(rendered).to match /this is the slicer body/
    expect(rendered).to match /this is the dicer body/
  end
end

假设这个局部视图:

<h3><%= widget.name %></h3>

<p><%= widget.body %></h3></p>

当然,您可以根据您喜欢的任何内容匹配字符串。