假设我想运行测试并创建许多Student
。每个学生都属于一所学校。学校名称由Faker宝石提供,但其数量有限,学生与这些学校相关联。
我能以一种让我重用现有学校的方式使用FactoryGirl吗?即。新的FactoryGirl.create(:student)
被分配给
FactoryGirl.create(:school)
class Student
belongs_to :school, class_name: 'SchoolSociety'
end
class School
has_many :students
field :name
end
我认为这与此无关,但我正在使用Mongoid。我的工厂看起来像
FactoryGirl.define do
factory :student, class: Student do
association(:school, factory: :school)
end
factory :school, class: School do
name { Faker::University.name }
end
end
一种解决方案是使用School.where(name: Faker::University.name)
,但我会失去FactoryGirls工厂的所有灵活性......
有没有更好的解决方法?
上下文正在与许多学生一起运行Cucumber测试
编辑:
我的实际黄瓜案例是根据涉及当前时间和注册用户数量(在学校注册)的数学公式测试累积奖金。我正在做一些像
这样的事情Scenario Outline: Jackpot increases with registrations and time
Given the current date is <date>
And <count> students have registered for the special event
When I am on the special event page
Then I should see "<jackpot> €"
Examples:
| date | count | jackpot |
| 2016/11/24 15:00:00 | 5 | 4 9 5 , 3 0 |
| 2016/11/30 15:00:00 | 10 | 4 9 7 , 6 0 |
| 2016/12/10 15:00:00 | 20 | 5 0 2 , 2 0 |
| 2016/12/10 15:00:00 | 150 | 6 5 2 , 2 0 |
现在,那些<count> students have registered for the special event
必须是属于现有学校的学生(这意味着,在注册过程中,他们必须注册一个学校电子邮件,其域名存在/可映射到School
in我们的DB)
答案 0 :(得分:0)
在使用黄瓜而不是让工厂规则决定创建的内容时,您应该具体而准确地了解您的Givens。所以,如果你想在同一所学校创建几个学生,我会有
Given there is a school with several students
如果你想要几所学校的学生
Given there are several schools with students
如果你想让一个学生注册多个学校
Given there is a student enrolled in two schools
显然,您可以通过执行
之类的操作来创建各种各样的创建交易当您实施这些步骤时,特别是当您开始时,它很有诱惑力将所有代码放在步骤中完成工作。抵制这一点,而不是在步骤中进行调用,并使调用与步骤描述匹配。例如
Given 'there is a school with several students' do
@school = create_school
@students = []
several.times do
@students << create_student school: school
end
end
此步骤使用两种方法create_school
和create_student
。您可以在辅助模块中定义这些
module SchoolsStepHelper
def create_school
...
def create_student(school: ...)
...
end
World SchoolsStepHelper
现在,您可以准确了解如何创建学生,以及何时遇到新事物,例如在两所学校注册的学生,您可以添加/修改您的方法以获得这些额外的功能,例如:你可以添加
def enroll_student(student: school:)
...
这样我们就可以了
Given 'there is a student enrolled in two schools' do
@student = create_student
@school_1 = create_school
@school_2 = create_schoo
enroll_student(student: @student, school: @school_1)
enroll_student(student: @student, school: @school_1)
end
现在我们的步骤定义中仍然有太多代码,所以我们需要重构。在这里我们有几个选择
将这个复合步骤分解为更简单的步骤,以便学生和学校已经存在,例如
鉴于有哈佛学校 还有耶鲁学校 还有一个学生弗雷德 弗雷德就读于耶鲁大学和哈佛大学。
您可以通过这种方式使您的方案更具描述性,尤其是在开发注册功能时
提取更高级别的方法
鉴于'有一所学生就读于两所学校' @student = create_dual_enrolled_student 端
您选择哪种方法,您将重复使用我们在本答案开头创建的简单方法。
现在关于工厂的问题基本上是一个实现细节,关于你如何创造事物。应该可以
实施一个解决方案,需要很少或根本不了解工厂,以了解发生的事情。 (只是非常简单的工厂调用你的方法)
实施一个甚至不使用工厂的解决方案(这是我赞成的方法,但这是另一个故事)。
最后,如果您采用这种方法并且所有步骤定义都是作为简单调用实现的,那么如果您有许多类似的步骤定义就没关系,例如。
Given there is a student
Given Fred is a student
Given there is a student Fred
Given there is a student Sue
您可以为每一个创建一个步骤定义,而不会产生重复,因为调用不会重复,额外步骤的成本只是通过实现的简单性和不需要参数或正则表达式来平衡。
Given 'there is a student' do
create_student
end
Given 'Fred is a student' do
create_student name: 'Fred'
end
Given there is a student Fred do
create_student name: Fred
end
Given 'there is a student Sue' do
create_student name: 'Sue'
end
Phew这是一个很长的答案,我希望它有用。