如何为@ post.tags.map这样的东西编写规范?

时间:2012-11-29 11:28:15

标签: ruby-on-rails rspec

我在帖子标记模型之间存在多对多关联。 然后,我在帖子视图中有以下内容:

帖/ show.html.erb:

<p><%= raw @post.tags.map { |t| link_to t.name, tag_path(t.name) }.join(', ') %></p>

这是我写的规范:

post_pages_spec.rb:

  describe "show page" do
    let!(:post) { FactoryGirl.create(:post, user:        user,
                                            title:       "Lorem",
                                            content:     "Lorem ipsum",
                                            category_id: category.id,
                                            tag_list:     "#{tag.id}") }

    before do 
      sign_in user
      visit post_path(post)
    end

    it { should have_selector('h1',       text: post.title) }
    it { should have_selector('title',    text: post.title) }
    it { should have_link(post.user.name, href: user_path(user)) }
    it { should have_selector('p',        text: post.content) }
    it { should have_selector('p',        text: post.category.name) }
    it { find("p").should have_content(post.tags.map { |t| t.name }.join(", ")) }
    .
    .
    .

我收到了这个错误:

  

故障:

     

1)帖子页面显示页面        失败/错误:它{find(“p”)。应该has_content(post.tags.map {| t | t.name} .join(“,”))}          预计“Lorem ipsum”中的内容为“1,tag28”        './spec/requests/post_pages_spec.rb:28:in'块(3级)in'

代码在真实网站中有效,但正如您所看到的,规范失败了。编写此规范的正确方法是什么?

修改

帖子模型的一个例子(以防万一):

class Post < ActiveRecord::Base
  include ActionView::Helpers

  attr_accessible :title, :content, :category_id, :tag_list

  has_many :taggings, :dependent => :destroy  
  has_many :tags, :through => :taggings
  .
  .
  .

来自实时网站的输出:

  <p><a href="/tags/inkscape">inkscape</a>, <a href="/tags/gimp">gimp</a></p>

2 个答案:

答案 0 :(得分:1)

如果您想为规范使用it { ... }构造,则应在顶部定义it,如:

subject { page }

我不记得请求规范的默认主题是什么,但通常我会按照描述定义subject

答案 1 :(得分:1)

<强>更新

在评论主题中,我们发现用简单的find替换have_selector会传递:

it { should have_selector('p', text: post.tags.map { |t| t.name }.join(", ")) }

目前尚不清楚为什么find('p').should have_content(...)不起作用。我已经测试了相同类型的视图(包含链接列表的<p>标签)并发现find('p').should ...模式工作正常,因此您的代码中会发生一些有趣的事情。它可能与Capybara 2.0中have_content的问题有关,也可能没有,我将在下面讨论。

如果有任何想法请分享!这是我能提供的最好的。

原始回答

Capybara 2.0 excludes content that is not visible中的新文本匹配器,稍微产生unintuitive results

it { should have_selector('title', text: 'Some Title') } # <= fails
it { should have_selector('title') }                     # <= passes
it { should have_text('Some Title') }                    # <= passes

并且,与此问题中的案例相关,this

find("title").should have_content("some text") # <= fails

另见帖子:How can I test the page title with Capybara 2.0?

如果page.body.should ...正在运行但是page.should ...(或另一种形式,subject { page} ; it { should ... })不是,那么这可能就是问题所在。请注意,page.body是一个HTML字符串,而pageCapybara::Session,它们完全不同,尽管在Capybara 2.0中看起来至少可以满足您的预期。我认为page.body包含所有 HTML,因此会绕过可见性问题。