FactoryGirl关联,控制器属性,无关实例

时间:2013-07-14 18:05:51

标签: ruby-on-rails rspec controller factory-bot rspec-rails

我很难让FactoryGirl协会在我的控制器中工作。

保存了许多'Idea'实例,这导致'将所有想法分配为@ideas'规范失败。我不确定为什么。对于此设置,我不希望只有一个实例保留在数据库中吗?如果我一次又一次地运行规范,每次额外实例的数量会翻倍。我的理解是使用“Idea.create!”在我的规范中,如下所示将为测试创建一个对象,然后将其从数据库中删除以进行下一次运行。

我有一个使用纳秒的独特电子邮件序列,以避免重复的电子邮件。使用FactoryGirl序列计数器时,我一直收到电子邮件已存在的错误,这可能与此问题直接相关。我怎样才能更有效地解决这个问题?

摘自/controllers/ideas_controller_spec.rb:

  valid_attributes = FactoryGirl.attributes_for(:idea)

  describe "GET index" do
    it "assigns all ideas as @ideas" do
      idea = Idea.create! valid_attributes
      get :index, {}, valid_session
      assigns(:ideas).should eq([idea])
    end
  end

工厂/ idea.rb:

FactoryGirl.define do
  factory :idea do
    brief 'Valid brief for an idea'
    phase 1
    active true
    industry 'Technology'
    user
  end
end

工厂/ user.rb

FactoryGirl.define do
  factory :user do
    sequence(:email) {
      |n| time = Time.new
      "person#{time.usec}@example.com"
    }
    password               '12345678'
    password_confirmation  '12345678'
  end
end

规范输出(运行“bundle exec rake db:test:prepare”后立即执行):

1) IdeasController GET index assigns all ideas as @ideas
     Failure/Error: assigns(:ideas).should eq([idea])

       expected: [#<Idea id: 6, phase: 1, brief: "Valid brief for an idea", image: nil, active: true, industry: "Technology", created_at: "2013-07-14 17:40:57", updated_at: "2013-07-14 17:40:57", user_id: nil>]
            got: #<ActiveRecord::Relation [#<Idea id: 1, phase: 1, brief: "Valid brief for an idea", image: nil, active: true, industry: "Technology", created_at: "2013-07-14 17:40:57", updated_at: "2013-07-14 17:40:57", user_id: 3>, #<Idea id: 2, phase: 1, brief: "Valid brief for an idea", image: nil, active: true, industry: "Technology", created_at: "2013-07-14 17:40:57", updated_at: "2013-07-14 17:40:57", user_id: 5>, #<Idea id: 3, phase: 1, brief: "Valid brief for an idea", image: nil, active: true, industry: "Technology", created_at: "2013-07-14 17:40:57", updated_at: "2013-07-14 17:40:57", user_id: 9>, #<Idea id: 4, phase: 1, brief: "Valid brief for an idea", image: nil, active: true, industry: "Technology", created_at: "2013-07-14 17:40:57", updated_at: "2013-07-14 17:40:57", user_id: 11>, #<Idea id: 5, phase: 1, brief: "Valid brief for an idea", image: nil, active: true, industry: "Technology", created_at: "2013-07-14 17:40:57", updated_at: "2013-07-14 17:40:57", user_id: 14>, #<Idea id: 6, phase: 1, brief: "Valid brief for an idea", image: nil, active: true, industry: "Technology", created_at: "2013-07-14 17:40:57", updated_at: "2013-07-14 17:40:57", user_id: nil>]>

       (compared using ==)

       Diff:
       @@ -1,2 +1,7 @@
       -[#<Idea id: 6, phase: 1, brief: "Valid brief for an idea", image: nil, active: true, industry: "Technology", created_at: "2013-07-14 17:40:57", updated_at: "2013-07-14 17:40:57", user_id: nil>]
       +[#<Idea id: 1, phase: 1, brief: "Valid brief for an idea", image: nil, active: true, industry: "Technology", created_at: "2013-07-14 17:40:57", updated_at: "2013-07-14 17:40:57", user_id: 3>,
       + #<Idea id: 2, phase: 1, brief: "Valid brief for an idea", image: nil, active: true, industry: "Technology", created_at: "2013-07-14 17:40:57", updated_at: "2013-07-14 17:40:57", user_id: 5>,
       + #<Idea id: 3, phase: 1, brief: "Valid brief for an idea", image: nil, active: true, industry: "Technology", created_at: "2013-07-14 17:40:57", updated_at: "2013-07-14 17:40:57", user_id: 9>,
       + #<Idea id: 4, phase: 1, brief: "Valid brief for an idea", image: nil, active: true, industry: "Technology", created_at: "2013-07-14 17:40:57", updated_at: "2013-07-14 17:40:57", user_id: 11>,
       + #<Idea id: 5, phase: 1, brief: "Valid brief for an idea", image: nil, active: true, industry: "Technology", created_at: "2013-07-14 17:40:57", updated_at: "2013-07-14 17:40:57", user_id: 14>,
       + #<Idea id: 6, phase: 1, brief: "Valid brief for an idea", image: nil, active: true, industry: "Technology", created_at: "2013-07-14 17:40:57", updated_at: "2013-07-14 17:40:57", user_id: nil>]

     # ./spec/controllers/ideas_controller_spec.rb:37:in `block (3 levels) in <top (required)>'

2 个答案:

答案 0 :(得分:0)

我猜你们已经为rspec关闭了交易,这会导致数据库的增长,如你所观察到的那样。

请注意,自从Rails 4.0起,ActiveRecord返回Relation而不是Array时,您也遇到了问题,因此您需要使用to_a在将其与Array进行比较之前的方法。

答案 1 :(得分:0)

你实际上并没有真正使用Factorygirl序列。序列背后的想法是每次调用工厂时n中的变量sequence(:email) { |n| .. }都会增加。这意味着使用

就足够了
    sequence(:email) { |n| "person#{n}@example.com" }

或者当您想要使用时间时,您可以写:

    email { "person#{Time.new.usec}@example.com" }

这里的方括号表示内部代码在调用工厂时执行,而不是更早,因为没有括号时会发生。

但这只是一个评论,这不应该产生问题。

正如您所说,问题可能是该对象的太多实例仍留在数据库中。为此,一个简单的解决方案是使用database cleaner gem,它会在每个测试用例后从数据库中删除添加的实例。