gpt4 book ai didi

ruby-on-rails - Rails 教程 : RSpec test decoupling

转载 作者:行者123 更新时间:2023-12-04 06:27:55 26 4
gpt4 key购买 nike

我正在尝试 Exercise 2 of Chapter 8.5在迈克尔·哈特尔的 Ruby on Rails Tutorial .练习如下:

按照第 8.3.3 节中的示例,浏览用户和身份验证请求规范(即当前位于 spec/requests 目录中的文件)并在 spec/support/utilities.rb 中定义实用程序函数以将测试与实现分离。额外的功劳:将支持代码组织到单独的文件和模块中,并通过将模块正确地包含在规范帮助文件中来使一切正常工作。

示例 8.3.3:实用程序.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

定义 valid_signin(user)函数用于 authentication_pages_spec.rb 的以下 block 中并且工作正常。
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

因此,通过这个示例,我开始创建自己的名称 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

我在 user_pages_spec.rb 中使用这个 block 像这样:
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

它不起作用。 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 '

这些错误似乎暗示了我的 valid_signup(user) 中的 user.name utilities.rb中的函数没有定义,但我看不出有什么原因。我已经多次重启 Guard,并执行了 rake db:test:prepare确保测试数据库(使用 postgresql)是有序的。

这是我的 factories.rb为了完整性:
FactoryGirl.define do
factory :user do
name "Example User"
email "user@example.com"
password "foobar"
password_confirmation "foobar"
end
end

在我继续尝试解耦更多的测试套件之前,我非常想解决这个错误,更重要的是,了解它的原因。

编辑

我已经尝试过您的提示,并在 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
end

由于我删除了 let(:user){FactoryGirl.create(:user)}从函数中我猜到函数中不再创建用户所以我需要定义 valid_signup(user)user 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"
end

这不起作用,并给了我以下错误:
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: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 '


我还尝试使用 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 '

接下来我尝试在不传递变量的情况下运行它 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"
end

这返回:
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 '

仍然没有更接近答案。我可能忽略了一些简单的事情。不知道是什么。不过,我得到了我第一次做错的事情:我只是认为 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

关于 FactoryGirl 使用的更多信息: https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#using-factories

关于ruby-on-rails - Rails 教程 : RSpec test decoupling,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13606603/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com