我非常喜欢RSpec能够分离控制器和视图测试的方式,但是在使用水豚匹配器在视图测试中工作时会遇到一些问题。我基本上试图实现的是这样的:
describe "some page" do
it "should render with lots of stuff" do
assign ..
render
rendered.should have_button ('Any button') #or any capybara matcher, really
end
end
我在网上看到一些帖子显示如何配置capybara和rails3以便与黄瓜或rspec控制器测试一起顺利运行,但这不是我想要的 - 也就是说,可能在最低级别测试视图。
此外,如果有另一种方法可以做到这一点(不需要大量的自定义代码,我知道我可以编写一些匹配器,使用nokogiri或任何适合的工具提取给定的选择器),这也很棒 - 使用capybara是不是要求。
答案 0 :(得分:17)
现在可以选择在测试控制器(以及视图)时使用Capybara匹配器(没有Webrat行李)。我这样用它:
describe GlobalizeTranslationsController do
render_views
let(:page) { Capybara::Node::Simple.new(@response.body) }
describe "PUT :update" do
before do
put :update
end
it "displays a flash notice" do
page.should have_selector('p.notice')
end
end
end
完整代码:
参考文献:
答案 1 :(得分:11)
Capybara目前不适用于视图规范(有计划在未来使用它)。最简单的答案是只需将gem 'webrat'
添加到Gemfile中,基本上就可以了。您可能没有have_button
,但您将拥有have_selector
,have_tag
和类似内容。
答案 2 :(得分:9)
比Pawel的答案稍微简单,但要点是一样的;以下适用于rails 3.1.0,rspec 2.6.0,capybara 1.1.1:
page = Capybara::Node::Simple.new( rendered )
page.should have_content( "blah" )
答案 3 :(得分:3)
你不能在rendered
上调用capybara的方法,这只是一个字符串。您可以使用Capybara's string method将rendered
包裹在Capybara节点中。然后,您可以在该节点上调用Capybara的方法:
describe "some page" do
it "should render with lots of stuff" do
assign ..
render
Capybara.string(rendered).should have_button('Any button')
end
end
有关详细信息,请查看此帖:
http://www.tamingthemindmonkey.com/2011/11/07/capybara-matchers-and-scoping-in-view-specs
答案 4 :(得分:1)
在本页底部的“Webrat和Capybara”部分中,看来Capybara不支持rspec视图规范
答案 5 :(得分:1)
由于添加了大多数其他答案后事情发生了变化,因此更新了这个旧问题:
Capybara现在支持视图规范(开箱即用),这在Capybara's master branch上有记录。
引用文档:
最后,视图规范支持Capybara匹配器:
RSpec.describe "todos/show.html.erb", type: :view do
it "displays the todo title" do
assign :todo, Todo.new(title: "Buy milk")
render
expect(rendered).to have_css("header h1", text: "Buy milk")
end
end
在早期版本中添加了对没有附加let(:page)
样式代码的支持。 (它在Capybara 2.4.4和2.2中为我工作)
另请注意,仅支持有限的匹配器子集;但是,您可以使用Capybara.string获得更多功能;例如:
expect(Capybara.string(rendered).first('td')).to have_no_content 'Tom Riddle'
答案 6 :(得分:0)
您也可以使用capybara语法
describe "some page" do
it 'should render hello with name' do
assign(:user, double("User", first_name: "John"))
render
expect(rendered).to have_content("Hello John")
end
end