你能明确地在FactoryGirl中输入一个方法的返回值吗?

问题描述:

假设我有以下Rails模型,并且显示的方法已经过测试。现在你能明确地在FactoryGirl中输入一个方法的返回值吗?

class Employee < ActiveRecord::Base 
    has_many :jobs 

    def total_annual_income 
    jobs.collect { |j| j.annual_salary}.sum 
    # Or some other AR magic to do it directly in the database; doesn't matter 
    end 
end 

class Job < ActiveRecord::Base 
    # property :annual_salary 

    belongs_to :employee 
end 

,假设我要去别的地方写一些其他的方法调用Employee#total_annual_income。当我使用FactoryGirl测试此方法时,是否可以直接使用total_annual_income属性设置我的Employee工厂,而不必制作相应的Job工厂?即,可我只是做

FactoryGirl.define do 
    factory :employee1, class: Employee do 
    id 100 
    total_annual_income 100000.0 
    end 
end 

代替

FactoryGirl.define do 
    factory :employee1, class: Employee do 
    id 100 
    end 
end 

# WANT TO OMIT THIS ENTIRE SET OF FACTORIES # 
FactoryGirl.define do 
    factory :employee1_job1, class: Job do 
    id 100 
    employee_id 100 
    annual_salary 60000.0 
    end 
    factory :employee1_job2, class: Job do 
    id 101 
    employee_id 100 
    annual_salary 40000.0 
    end 
end 
# WANT TO OMIT THIS ENTIRE SET OF FACTORIES # 

我有点新FactoryGirl还在,所以如果道歉,我忽略了一些基本的东西。

看一看工厂女孩文件下的关联信息:

https://github.com/thoughtbot/factory_girl/blob/master/GETTING_STARTED.md#associations

这有一个使用#create_list产生的职位列表为用户的:user_with_posts一个例子 - 有点像你的列表的工作。由于在计算器上,习惯上包括完整的答案的情况下,外部链接应该成为坏了,这里的copypasta其意见的例子:对的has_many关系

生成的数据是有点更复杂,这取决于量所需的灵活性,但这里有一个生成相关数据的绝对例子。

FactoryGirl.define do 

    # post factory with a `belongs_to` association for the user 
    factory :post do 
    title "Through the Looking Glass" 
    user 
    end 

    # user factory without associated posts 
    factory :user do 
    name "John Doe" 

    # user_with_posts will create post data after the user has been created 
    factory :user_with_posts do 
     # posts_count is declared as a transient attribute and available in 
     # attributes on the factory, as well as the callback via the evaluator 
     transient do 
     posts_count 5 
     end 

     # the after(:create) yields two values; the user instance itself and the 
     # evaluator, which stores all values from the factory, including transient 
     # attributes; `create_list`'s second argument is the number of records 
     # to create and we make sure the user is associated properly to the post 
     after(:create) do |user, evaluator| 
     create_list(:post, evaluator.posts_count, user: user) 
     end 
    end 
    end 
end 

这让我们这样做:

create(:user).posts.length # 0 
create(:user_with_posts).posts.length # 5 
create(:user_with_posts, posts_count: 15).posts.length # 15 

这样做的核心是真的以上显示,#create_list方法。

[编辑] 完全未经检验的,我想你的榜样变成类似:

FactoryGirl.define do 
    factory :employee_with_jobs, class: Employee do 
    id 100 

    transient do 
     jobs_count 2 
    end 

    after(:create) do |employee, evaluator| 
     create_list(:job, evaluator.jobs_count, 
        employee: employee, 
        annual_salary: 40000.0) 
    end 
    end 
end 

create(:employee_with_jobs, jobs_count: 5) # Expecting total salary 200000.0. 

...更多或更少。