我正在运行 Rails 3.1.1、RSpec 2.7.0 和 HAML 3.1.3。
假设我有以下 View 文件:
应用程序/ View /布局/application.html.haml
!!!
%html
%head
%title Test
= stylesheet_link_tag "application"
= javascript_include_tag "application"
= csrf_meta_tags
%body
= content_for?(:content) ? yield(:content) : yield
应用程序/ View /布局/companies.html.haml
- content_for :content do
#main
= yield :main
#sidebar
= yield :sidebar
= render :template => 'layouts/application'
应用程序/ View /公司/index.html.haml
- content_for :main do
%h1 MainHeader
- content_for :sidebar do
%h1 SidebarHeader
以及以下规范文件:
规范/ View /公司/index_spec.rb
require 'spec_helper'
describe 'companies/index.html.haml' do
it 'should show the headers' do
render
rendered.should contain('MainHeader')
rendered.should contain('SidebarHeader')
end
end
当我运行 RSpec 时,我收到以下错误:
1) companies/index.html.haml should show the headers
Failure/Error: rendered.should contain('MainHeader')
expected the following element's content to include "MainHeader":
# ./spec/views/companies/index_spec.rb:7:in `block (2 levels) in <top (required)>'
起初,我认为 RSpec 在渲染 View 文件时以某种方式丢失了 content_for block 。但是,我无法在 RSpec 的 github 存储库中找到任何与它相关的问题,所以我不确定这应该归咎于谁。
我发现的一个(最近的)解决方案是 http://www.dixis.com/?p=571 .但是,当我尝试建议的代码时
view.instance_variable_get(:@_content_for)
它返回零。
最佳答案
将 Rspec 2 与 Rails 3 一起使用,为了编写用于 content_for 的 View 规范,请执行以下操作:
view.content_for(:main).should contain('MainHeader')
# instead of contain() I'd recommend using have_tag (webrat)
# or have_selector (capybara)
p.s.默认情况下 content_for(...) block 的值是一个空字符串,所以如果你想
编写规范显示没有调用 content_for(:main) 的情况,使用:
view.content_for(:main).should be_blank
您的规范可以写成:
it "should show the headers" do
render
view.content_for(:main).should contain('MainHeader')
view.content_for(:side_header).should contain('SidebarHeader')
end
这样,您的规范就可以准确地显示您的 View 所做的事情,而与任何布局无关。对于 View 规范,我认为单独测试它是合适的。编写 View 规范总是有用的吗?这是一个悬而未决的问题。
相反,如果您想编写规范以显示提供给用户的标记是什么样的,那么您将需要请求规范或 cucumber 功能。第三种选择是包含 View 的控制器规范。
p.s.如果您需要指定一个直接输出一些标记并将其他标记委托(delegate)给 content_for() 的 View ,您可以这样做:
it "should output 'foo' directly, not as a content_for(:other) block" do
render
rendered.should contain('foo')
view.content_for(:other).should_not contain('foo')
end
it "should pass 'bar' to content_for(:other), and not output 'bar' directly" do
render
rendered.should_not contain('bar')
view.content_for(:other).should contain('bar')
end
这可能是多余的,但我只是想展示 render() 如何填充 render 和 view.content_for。 “rendered”包含 View 直接产生的任何输出。 “view.content_for()”查找 View 通过 content_for() 委托(delegate)的任何内容。
关于ruby-on-rails-3 - 导轨 3 + Rspec 2 : Testing content_for,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8014038/