如何生成 :attributes_for 一个已经创建的工厂?
How can I generate :attributes_for an already created Factory?
更新(不要回答这个问题)
我才知道这个问题其实没有意义。这是基于我自己对工厂及其工作方式的误解。
整个想法是基于对 FactoryBot 工作原理的误解,特别是出于某种原因,我认为 FactoryBot 正在设置一些完全不同的 gem (Devise) 实际上负责的变量。
有什么简单的方法可以访问已建工厂的 'virtual attributes' 吗?
类似 :attributes_for 的内容,但用于工厂实例而不是 class?
所以你可以这样做:
FactoryBot.define do
factory :user do
email { Faker::Internet.email }
password { "password" }
password_confirmation { "password" }
end
end
@user = FactoryBot.build(:user)
@user.factory_attributes # Not a real method
#-> { email: "name@gmail.com", password: "123456", password_confirmation: "123456" }
为什么我想要这个
如果您想知道,我希望这能够缩短 'Login' 请求规范的以下代码。
来自这里:
let(:user_attributes) do
FactoryBot.attributes_for(:user)
end
let(:user) do
FactoryBot.create(:user, user_attributes)
end
# Triggers the create method in let(:user)
# Necessary to ensure the user exists in the database before testing sign in.
before { user }
let(:user_params) do
{ user: user_attributes }
end
it "redirects to the root path on successful sign in" do
post user_session_path(params: user_params)
expect(response).to redirect_to(root_path)
end
为此:
let(:user) do
FactoryBot.create(:user)
end
let(:user_params) do
{ user: user.factory_attributes }
end
it "redirects to the root path on successful sign in" do
post user_session_path(params: user_params)
expect(response).to redirect_to(root_path)
end
这比第一个更清晰,也更容易混淆,特别是对于新开发者(可以看到一些 RSpec 经验很少的人花了很多时间试图弄清楚这行到底是什么 "before { user }" 正在做)
FactoryBot.build(:user)
return 是 ActiveRecord
模型的一个实例。因此,您可以只使用 ActiveRecord::Base#attributes
到 return 当前对象的属性列表:
@user = FactoryBot.build(:user)
@user.attributes
一旦工厂 return 编辑了 User
的一个实例,user
就没有关于它是如何初始化的信息了。因此,不可能读取实例上不存在的值。
解决方法可能是这样的:
let(:parameters) do
{ user: FactoryBot.attributes_for(:user) }
end
before do
FactoryBot.create(:user, parameters[:user])
end
it "redirects to the root path on successful sign in" do
post user_session_path(params: parameters)
expect(response).to redirect_to(root_path)
end
但实际上,我认为您应该更明确地说明您真正关心的属性。您关心用户的电子邮件和用户密码——所有其他属性与本规范无关。因此我会这样写规范:
let(:email) { 'foobar@example.tld' }
let(:password) { 'secret' }
before do
FactoryBot.create(:user, email: email, password: password, password_confirmation: password)
end
it "redirects to the root path on successful sign in" do
post user_session_path(params: { user: { email: email, password: password } })
expect(response).to redirect_to(root_path)
end
Is there any easy way to access the 'virtual attributes' for an already built factory?
我认为您对术语感到困惑 and/or 工厂机器人的工作原理。您不建造 工厂 。工厂已经存在,它构建了 users(在本例中)。
用户在 built/created 之后,就不知道是哪个工厂制造的了。确实如此。可以通过多种方式创建用户。如果该方法确实存在,当您使用 User.create
创建用户时,您希望它 return 是什么?
更新(不要回答这个问题)
我才知道这个问题其实没有意义。这是基于我自己对工厂及其工作方式的误解。
整个想法是基于对 FactoryBot 工作原理的误解,特别是出于某种原因,我认为 FactoryBot 正在设置一些完全不同的 gem (Devise) 实际上负责的变量。
有什么简单的方法可以访问已建工厂的 'virtual attributes' 吗?
类似 :attributes_for 的内容,但用于工厂实例而不是 class?
所以你可以这样做:
FactoryBot.define do
factory :user do
email { Faker::Internet.email }
password { "password" }
password_confirmation { "password" }
end
end
@user = FactoryBot.build(:user)
@user.factory_attributes # Not a real method
#-> { email: "name@gmail.com", password: "123456", password_confirmation: "123456" }
为什么我想要这个
如果您想知道,我希望这能够缩短 'Login' 请求规范的以下代码。
来自这里:
let(:user_attributes) do
FactoryBot.attributes_for(:user)
end
let(:user) do
FactoryBot.create(:user, user_attributes)
end
# Triggers the create method in let(:user)
# Necessary to ensure the user exists in the database before testing sign in.
before { user }
let(:user_params) do
{ user: user_attributes }
end
it "redirects to the root path on successful sign in" do
post user_session_path(params: user_params)
expect(response).to redirect_to(root_path)
end
为此:
let(:user) do
FactoryBot.create(:user)
end
let(:user_params) do
{ user: user.factory_attributes }
end
it "redirects to the root path on successful sign in" do
post user_session_path(params: user_params)
expect(response).to redirect_to(root_path)
end
这比第一个更清晰,也更容易混淆,特别是对于新开发者(可以看到一些 RSpec 经验很少的人花了很多时间试图弄清楚这行到底是什么 "before { user }" 正在做)
FactoryBot.build(:user)
return 是 ActiveRecord
模型的一个实例。因此,您可以只使用 ActiveRecord::Base#attributes
到 return 当前对象的属性列表:
@user = FactoryBot.build(:user)
@user.attributes
一旦工厂 return 编辑了 User
的一个实例,user
就没有关于它是如何初始化的信息了。因此,不可能读取实例上不存在的值。
解决方法可能是这样的:
let(:parameters) do
{ user: FactoryBot.attributes_for(:user) }
end
before do
FactoryBot.create(:user, parameters[:user])
end
it "redirects to the root path on successful sign in" do
post user_session_path(params: parameters)
expect(response).to redirect_to(root_path)
end
但实际上,我认为您应该更明确地说明您真正关心的属性。您关心用户的电子邮件和用户密码——所有其他属性与本规范无关。因此我会这样写规范:
let(:email) { 'foobar@example.tld' }
let(:password) { 'secret' }
before do
FactoryBot.create(:user, email: email, password: password, password_confirmation: password)
end
it "redirects to the root path on successful sign in" do
post user_session_path(params: { user: { email: email, password: password } })
expect(response).to redirect_to(root_path)
end
Is there any easy way to access the 'virtual attributes' for an already built factory?
我认为您对术语感到困惑 and/or 工厂机器人的工作原理。您不建造 工厂 。工厂已经存在,它构建了 users(在本例中)。
用户在 built/created 之后,就不知道是哪个工厂制造的了。确实如此。可以通过多种方式创建用户。如果该方法确实存在,当您使用 User.create
创建用户时,您希望它 return 是什么?