Nic*_*ten 8 rspec ruby-on-rails railstutorial.org
我正在尝试在Michael Hartl的Ruby on Rails教程中进行第8.5章练习2.演习如下:
按照第8.3.3节中的示例,浏览用户和身份验证请求规范(即当前在spec/requests目录中的文件),并在spec/support/utilities.rb中定义实用程序函数,以将测试与实现分离.额外的功劳:将支持代码组织到单独的文件和模块中,并通过在spec帮助文件中正确包含模块来使一切工作正常.
例8.3.3:utilities.rb
include ApplicationHelper
def valid_signin(user)
fill_in "Email", with: user.email
fill_in "Password", with: user.password
click_button "Sign in"
end
RSpec::Matchers.define :have_error_message do |message|
match do |page|
page.should have_selector('div.alert.alert-error', text: message)
end
end
Run Code Online (Sandbox Code Playgroud)
已定义的valid_signin(user)函数用于以下块中authentication_pages_spec.rb并且工作正常.
describe "with valid information" do
let(:user){FactoryGirl.create(:user)}
before { valid_signin(user) }
it { should have_selector('title', text: user.name) }
it { should have_link('Profile', href: user_path(user)) }
it { should have_link('Sign out', href: signout_path) }
it { should_not have_link('Sign in', href: signin_path) }
describe "followed by signout" do
before { click_link "Sign out" }
it { should have_link('Sign in') }
end
end
Run Code Online (Sandbox Code Playgroud)
所以在这个例子中,我开始创建自己的名字valid_signup(user):
def valid_signup(user)
fill_in "Name", with: user.name
fill_in "Email", with: user.email
fill_in "Password", with: user.password
fill_in "Confirmation", with: user.password_confirmation
end
Run Code Online (Sandbox Code Playgroud)
我正在使用这个块user_pages_spec.rb:
describe "with valid information" do
let(:user){FactoryGirl.create(:user)}
before { valid_signup(user) }
it "should create a user" do
expect { click_button submit }.to change(User, :count).by(1)
end
describe "after saving the user" do
before { click_button submit }
let(:user) { User.find_by_email(user.email) }
it { should have_selector('title', text: user.name) }
it { should have_selector('div.alert.alert-success', text: 'Welcome') }
it { should have_link('Sign out') }
end
end
Run Code Online (Sandbox Code Playgroud)
它不起作用.Spork/Guard报告这些错误:
Failures:
1) UserPages signup with valid information should create a user
Failure/Error: expect { click_button submit }.to change(User, :count).by(1)
count should have been changed by 1, but was changed by 0
# ./spec/requests/user_pages_spec.rb:46:in `block (4 levels) in '
2) UserPages signup with valid information after saving the user
Failure/Error: before { valid_signup(user) }
NoMethodError:
undefined method `name' for nil:NilClass
# ./spec/support/utilities.rb:10:in `valid_signup'
# ./spec/requests/user_pages_spec.rb:43:in `block (4 levels) in '
3) UserPages signup with valid information after saving the user
Failure/Error: before { valid_signup(user) }
NoMethodError:
undefined method `name' for nil:NilClass
# ./spec/support/utilities.rb:10:in `valid_signup'
# ./spec/requests/user_pages_spec.rb:43:in `block (4 levels) in '
4) UserPages signup with valid information after saving the user
Failure/Error: before { valid_signup(user) }
NoMethodError:
undefined method `name' for nil:NilClass
# ./spec/support/utilities.rb:10:in `valid_signup'
# ./spec/requests/user_pages_spec.rb:43:in `block (4 levels) in '
Run Code Online (Sandbox Code Playgroud)
错误似乎表明我的valid_signup(user)函数中的user.name utilities.rb没有定义,但我没有看到任何理由.我已经多次重启Guard了,并rake db:test:prepare确保测试db(使用postgresql)是有序的.
这是我factories.rb的完整性:
FactoryGirl.define do
factory :user do
name "Example User"
email "user@example.com"
password "foobar"
password_confirmation "foobar"
end
endRun Code Online (Sandbox Code Playgroud)
在我继续尝试解耦更多测试套件之前,我非常希望解决此错误,更重要的是,了解它的原因.
编辑
我已经尝试了你的提示,并按user_pages_spec.rb如下方式编辑了该功能:
describe "with valid information" do
before { valid_signup(user) }
it "should create a user" do
expect { click_button submit }.to change(User, :count).by(1)
end
describe "after saving the user" do
before { click_button submit }
let(:user) { User.find_by_email('user@example.com') }
it { should have_selector('title', text: user.name) }
it { should have_selector('div.alert.alert-success', text: 'Welcome') }
it { should have_link('Sign out') }
end
endRun Code Online (Sandbox Code Playgroud)
由于我let(:user){FactoryGirl.create(:user)}从函数中删除了我猜测在函数中不再创建用户所以我需要定义valid_signup(user)为user变量for valid_signup不再由FactoryGirl填充:
def valid_signup(user)
fill_in "Name", with: "Example User"
fill_in "Email", with: "user@example.com"
fill_in "Password", with: "foobar"
fill_in "Confirmation", with: "foobar"
endRun Code Online (Sandbox Code Playgroud)
这没用,给了我以下错误:
Failures:
1) UserPages signup with valid information should create a user
Failure/Error: before { valid_signup(user) }
NameError:
undefined local variable or method user' for #<RSpec::Core::ExampleGroup::Nested_5::Nested_3::Nested_2:0x007fdafc5088c0>
# ./spec/requests/user_pages_spec.rb:42:inblock (4 levels) in '
2) UserPages signup with valid information after saving the user
Failure/Error: it { should have_selector('title', text: user.name) }
NoMethodError:
undefined method name' for nil:NilClass
# ./spec/requests/user_pages_spec.rb:52:inblock (5 levels) in '
我也尝试过valid_signup(user)以前用过它的方式运行测试(user.name, user.email, user.password, user.password_confirmation有的,也没用,有错误:
Failures:
1) UserPages signup with valid information should create a user
Failure/Error: before { valid_signup(user) }
NameError:
undefined local variable or method `user' for #
# ./spec/requests/user_pages_spec.rb:42:in `block (4 levels) in '
2) UserPages signup with valid information after saving the user
Failure/Error: it { should have_selector('title', text: user.name) }
NoMethodError:
undefined method `name' for nil:NilClass
# ./spec/requests/user_pages_spec.rb:52:in `block (5 levels) in 'Run Code Online (Sandbox Code Playgroud)
接下来我尝试运行它而不传递变量user_pages_spec.rb:before { valid_signup() }并且函数中没有变量utilities.rb:
def valid_signup()
fill_in "Name", with: "Example User"
fill_in "Email", with: "user@example.com"
fill_in "Password", with: "foobar"
fill_in "Confirmation", with: "foobar"
endRun Code Online (Sandbox Code Playgroud)
这返回:
Failures:
1) UserPages signup with valid information should create a user
Failure/Error: before { valid_signup(user) }
NameError:
undefined local variable or method `user' for #
# ./spec/requests/user_pages_spec.rb:42:in `block (4 levels) in '
2) UserPages signup with valid information after saving the user
Failure/Error: it { should have_selector('title', text: user.name) }
NoMethodError:
undefined method `name' for nil:NilClass
# ./spec/requests/user_pages_spec.rb:52:in `block (5 levels) in 'Run Code Online (Sandbox Code Playgroud)
仍然没有接近答案.我可能会忽略一些简单的事情.不知道是什么.我得到了我第一次做错的事情:我只是认为FactoryGirl是一种创建变量的方法,我不知道它实际上对我的测试数据库做了些什么.
我将尝试解释您的原始测试中发生的情况(我发现它比编辑后的版本更容易修复):
describe "with valid information" do
let(:user) {FactoryGirl.build(:user)} # FactoryGirl.create will save the instance, you should be using build instead
before { valid_signup(user) }
it "should create a user" do
expect { click_button submit }.to change(User, :count).by(1)
end
describe "after saving the user" do
before { click_button submit }
# let(:user) { User.find_by_email(user.email) } # this is not needed any more
it { should have_selector('title', text: user.name) }
it { should have_selector('div.alert.alert-success', text: 'Welcome') }
it { should have_link('Sign out') }
end
end
Run Code Online (Sandbox Code Playgroud)
有关 FactoryGirl 使用的更多信息:https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#using-factories
| 归档时间: |
|
| 查看次数: |
2188 次 |
| 最近记录: |