2012-11-29 19 views
0

我有一个标记模型之间的多对多关联。 然后,我有我的信息视图以下内容:如何为@ post.tags.map之类的内容编写规范?

帖子/ 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(", ")) } 
    . 
    . 
    . 

我得到这个错误:

Failures:

1) Post pages show page Failure/Error: it { find("p").should have_content(post.tags.map { |t| t.name }.join(", ")) } expected there to be content "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> 
+0

包含实际的'page.body',失败仅仅是说找到的元素有内容“Lorem ipsum”,所以它可能是由于许多可能的原因找到了错误的元素 – prusswan

+0

@prusswan对不起,什么你的意思是包含page.body? – alexchenco

+0

'page.body'是测试收到的实际html内容。 'page.body.should have_content ...'常见,你可以打印它来检查是否有缺失的元素 – prusswan

回答

1

更新

从评论跟帖,我们已经想通了,用一个简单的传球have_selector更换find

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

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

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

原来的答复

在水豚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,它们完全不同,尽管看起来在水豚2.0中至少可以针对两种方式运行您的期望。我认为page.body包括全部 HTML,因此绕过了可见性问题。

+0

谢谢,所以'page.body'是唯一的出路吗?或者是否有更好的方式来编写这个规范? – alexchenco

+1

老实说,我不太清楚。你会看到其他的答案,我们花了很多时间试图弄清楚世界上发生了什么,只是发现这是水豚的一个新怪癖。可能最好将问题发布到该github线程。 –

+0

所以水豚2.0已经是最后的了?我可怜的新人(和其他人)谁将被绊倒 – prusswan

1

如果你想使用您的规格的it { ... }结构,it应定义在顶部,如:

subject { page } 

我不记得什么是要求规格默认的主题,但通常所描述的我会定义subject

+0

我在文件顶部有'subject {page}'。 – alexchenco

+0

在这种情况下,请检查'find('p')'返回的内容。你可以尝试通过传递更多具体参数到'find'来完成它,或者完全没有它(只是使用page.body) – prusswan