2015-10-14 15 views
1

以下是我在documentation發現:如何使用rspec 3.3測試每個對象的部分渲染?

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 %> 

那麼,如何測試我的部件列表呈現局部的每個部件?

回答

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> 

當然,你可以根據你喜歡的任何東西來匹配字符串。

+0

但問題是一樣的(雖然它變得更理論)。如果我可以呈現一種類型的部分('<%= render @product%>'),我如何呈現另一種類型('<%= render @products%>')? –

+0

嗯(我可能在這裏記得不正確),但是在你的第一個例子中('<%= render @product%>'),Rails將查找一個名爲_product.html.erb的部分名稱,如果找不到。在第二個例子中,我認爲會發生完全相同的事情(雖然我不完全確定)。爲了驗證這一點,嘗試創建一個'_products.html.erb'部分並刪除'_product.html.erb'部分。爲了確保你呈現'_products.html.erb',你需要明確地調用它'<%= render'products',locals:{products:@products}%>'。這有道理嗎? – nicohvi