0

我在PostTag模型之间有一个多对多的关联 。然后,我的帖子视图中有以下内容:

帖子/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").should have_content(post.tags.map { |t| t.name }.join(", ")) } 期望有内容“ 1, tag28" in "Lorem ipsum" # ./spec/requests/post_pages_spec.rb:28:in `block (3 levels) 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>
4

2 回答 2

1

更新

从评论线程中,我们发现用find简单的have_selectorpass 替换了:

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

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

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

原始答案

Capybara 2.0 中的新文本匹配器排除了不可见的内容,产生了一些不直观的结果

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

并且,与这个问题中的案例相关,这个

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

另请参阅这篇文章:如何使用 Capybara 2.0 测试页面标题?

如果page.body.should ...正在工作但page.should ...(或以另一种形式,subject { page} ; it { should ... })不是,那么也许这就是问题所在。请注意,它page.body是一个 HTML 字符串,而page它是一个Capybara::Session,它们是完全不同的,尽管在 Capybara 2.0 中似乎至少你可以满足你的期望。我认为page.body包括所有HTML,因此绕过了可见性问题。

于 2012-11-29T12:07:27.793 回答
1

如果您想将it { ... }构造用于您的规范,it应在顶部定义,如:

subject { page }

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

于 2012-11-29T11:50:37.920 回答