【问题标题】:How to test rendering a partial for each object with rspec 3.3?如何使用 rspec 3.3 测试渲染每个对象的部分?
【发布时间】:2016-01-12 04:43:57
【问题描述】:

这是我在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 %>

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

【问题讨论】:

    标签: ruby-on-rails ruby rspec render


    【解决方案1】:

    好吧,由于renderedstring 只是返回视图实际呈现的内容(正如人们所期望的那样),因此行为符合预期。

    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>
    

    当然,你可以根据自己的喜好匹配字符串。

    【讨论】:

    • 但问题是一样的(尽管它变得更加理论化)。如果我可以渲染一种类型的部分 (&lt;%= render @product %&gt;) 我如何渲染另一种类型 (&lt;%= render @products %&gt;)?
    • 好吧(我可能在这里记错了),但在您的第一个示例 (&lt;%= render @product %&gt;) 中,Rails 将查找名为 _product.html.erb 的部分,如果找不到则抛出异常。在您的第二个示例中,我认为会发生完全相同的事情(尽管我不完全确定)。要验证这一点,请尝试创建 _products.html.erb 部分并删除 _product.html.erb 部分。为了确保你渲染_products.html.erb,你需要明确地调用它&lt;%= render 'products', locals: { products: @products } %&gt;。这有意义吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-24
    • 2013-06-18
    • 2010-09-11
    • 2021-09-17
    相关资源
    最近更新 更多