我有电子邮件工厂(spec / factories / email.rb):
FactoryGirl.define do
factory :email, class: String do
skip_create
transient do
username 'user'
subdomain 'mail'
domain_name 'example.com'
host { [subdomain, domain_name].compact.join('.') }
end
trait(:with_blank_host) { host '' }
trait(:with_blank_username) { username '' }
initialize_with { new("#{username}@#{host}") }
end
end
我有规格(spec / models / user_spec.rb):
RSpec.describe User, type: :model do
# ...
it { is_expected.to_not allow_value(FactoryGirl.create(:email, :with_blank_host)).for(:email) }
it { is_expected.to_not allow_value(FactoryGirl.create(:email, :with_blank_username)).for(:email) }
end
以这种方式使用FactoryGirl是否正确?这是不良做法吗?
假设创建没有主机名/用户名的电子邮件的逻辑将只在测试中使用。为什么要保留在工厂?
为什么不简单地做:
FactoryGirl.define do
factory :email, class: String do
skip_create
transient do
username 'user'
subdomain 'mail'
domain_name 'example.com'
host { [subdomain, domain_name].compact.join('.') }
end
initialize_with { new("#{username}@#{host}") }
end
end
RSpec.describe User, type: :model do
# ...
it 'should not allow blank host' do
is_expected.to_not allow_value(FactoryGirl.create(:email, host: '')).for(:email)
end
it 'should not allow blank username' do
is_expected.to_not allow_value(FactoryGirl.create(:email, username: '').for(:email)
end
end
除此之外,让工厂创建电子邮件字符串真的有意义吗?为什么不简单地使用字符串(这更简单):
is_expected.to_not allow_value(FactoryGirl.create(:email, host: '')).for(:email)
与
is_expected.to_not allow_value('test@').for(:email)
如果您希望通过测试获得一致的:email,为什么不将其放入用户。
FactoryGirl.define do
factory :user
transient do
username 'user'
subdomain 'mail'
domain_name 'example.com'
host { [subdomain, domain_name].compact.join('.') }
end
before(:create) do |user, evaluator|
user.email = "#{username}@#{host}"
end
end
end
但是,如果逻辑属于那些特定的测试,为什么要在工厂中对所有这些进行抽象而不是简单地使用前/回调。根据经验,我只会在工厂中的所有规范文件中使用逻辑,其他所有内容都在回调之前/之后正确
RSpec.describe User, type: :model do
before :each do
# logic before each test of the file
end
context 'email validation'
before :each do
# logic before each test concerning the email validation
# useful to factor stuff that will be used multiple time
# e.g.
# @email_ok = '[email protected]'
end
it 'should not allow blank host' do
# test specific setup
# useful for stuff only used in this test
# e.g
# email_no_host = 'user@'
# expectation
end
end
end
简而言之:
当然,您在做什么。这本身不是一个坏习惯。恕我直言,这没有多大意义。
已编辑
您也可以在测试范围内添加一个帮助程序,以免模型太胖:
RSpec.describe User, type: :model do
context 'email validation'
def generate_email(**opts)
options = {username: 'user', subdomain: 'mail', domain_name 'example.com'}.merge(opts)
username = options[:username]
host = options[:host] || "#{options[:subdomain]}.#{options[:domain_name]}"
"#{username}@#{host}"
end
it 'should not allow blank host' do
is_expected.to_not allow_value(generate_email host: '').for(:email)
end
# Here goes 100 other use of generate_email
end
end
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句