我正在学习《Ruby on Rails 3教程》这本书,遇到了需要为静态页面编写基本单元测试的部分。我发现代码只是一些文本更改后就被复制了,于是我将其更改为以下内容:
require 'spec_helper'
describe PagesController do
render_views
pages = ['home', 'contact', 'about', 'help']
before(:each) do
@base_title = "Ruby on Rails Tutorial Sample App | "
end
pages.each do |page|
describe "GET '#{page}'" do
it "should be successful" do
get "#{page}"
response.should be_success
end
it "should have the right title" do
get "#{page}"
response.should have_selector("title", :content => @base_title + page.capitalize)
end
end
end
end
在上面的例子中,让我感到困惑的是,我可以用以下内容替换'pages'变量:
@pages = ['home', 'contact', 'about', 'help']
它仍然有效。为什么?'@pages'和'pages'有何区别?
另一个令人困惑的事情是,这两者都会导致测试失败:
pages = ['home', 'contact', 'about', 'help']
@base_title = "Ruby on Rails Tutorial Sample App | "
并且
before(:each) do
pages = ['home', 'contact', 'about', 'help']
@base_title = "Ruby on Rails Tutorial Sample App | "
end
为什么上面的两个例子会失败?为什么代码必须像我在第一个代码片段中发布的那样?我认为这与变量作用域有关,但我还是 Ruby 的新手,所以我正在寻找更深入的理解。
顺便说一下,我是一名经验丰富的 C# 开发人员,因此获取可比较的 Java 或 C# 代码将帮助我理解,或者是一个写得很好的描述。
感谢任何支持。
编辑: 添加了当我将 @base_title 移出 'before' 块时的错误消息。
Failure/Error: response.should have_selector("title", :content => @base_title + page.capitalize)
NoMethodError:
You have a nil object when you didn't expect it!
You might have expected an instance of Array.
The error occurred while evaluating nil.+
# ./spec/controllers/pages_controller_spec.rb:21:in `block (4 levels) in <top (required)>'
@pages
(即实例变量,不是局部变量pages
),它是否有效? 在第一个代码片段中,需要提供更多上下文才能确定该方法的名称。对于第三个代码片段,如果使用实例变量@pages
而不是局部变量pages
,则应该可以正常工作。 - Zabba