【问题标题】:How to avoid Persistence of a Factory Girl object如何避免工厂女孩对象的持久性
【发布时间】:2011-07-21 11:43:28
【问题描述】:

我有几个使用 Factory_girl 的 rspec 测试。它在 Rails 3 应用程序中使用 MongoId 在 MongoDB 上使用。

在某个地方,我针对无效值进行测试:期待验证错误。之后,任何时候我打电话给Factory(:user),它都会失败,因为验证错误。当我调用 Factory(:user) 时,我会期待一个全新的、干净的对象,而不是一个被重复使用的、被破坏的对象。

下面的示例代码说明了 *user_spec.rb* 将无效项目添加到“角色”。用户模型成功地将记录标记为无效

在规范中,*sidebar_helper_spec.rb* 需要实例化 @user,但它失败了,告诉我无效角色“foo”在那里。但是你可以清楚的看到factory.rb中没有这个角色。

这是预期的行为吗?我可以使用配置选项切换持久性(或缓存?)吗?

## models/user_spec.rb

require 'spec_helper'
describe User do
  describe 'roles' do
    before(:each) do
      @user = Factory.build(:user)
    end
    it 'should require a role' do
      @user.roles = nil
      @user.should_not be_valid
    end
    it 'should allow one role from set of defined roles' do
      #@user.roles is preset in factory with "jobseeker"
      @user.should be_valid
    end
    it 'should reject undefined roles' do
      @user.roles << "foo"
      @user.should_not be_valid
    end
    it 'should allow multiple roles' do
      @user.roles = ["banned", "jobseeker"]
      @user.should be_valid
    end
  end
end

## helpers/sidebar_helper_spec.rb

require 'spec_helper'
describe SidebarHelper do
  before(:each) do
    @user = Factory.create(:user) #fails with Mongoid::Errors::Validations: Validation failed - Roles foo is an invalid role.
    @profile = Factory.create(:profile)
  end

  # Has many specs, but all Fail on error in the before(:each)
end

## Actual factory.rb

Factory.define :user do |f|
  f.password    'mischief managed'
  f.email       'h.potter@gryffindor.hogwards.edu.wiz'
  f.roles       ['jobseeker']
end
Factory.define :employer do |f|
  f.password    'butterscotch'
  f.email       'dumbledore@staff.hogwards.edu.wiz'
  f.roles       ['employer']
end

Factory.define :profile do |f|
  f.available true
  f.sync false
end

【问题讨论】:

    标签: rspec persistence factory-bot


    【解决方案1】:

    = 创建一个new 数组["banned", "jobseeker"] 并将其设置为@user.roles

    # should allow multiple roles
    @user.roles = ["banned", "jobseeker"]
    

    BUT &lt;&lt; 追加 "foo" 到已经存在的数组(即修改现有数组!):

    # should reject undefined roles
    @user.roles << "foo"
    

    FactoryGirl 不是重复使用相同的用户对象,而是重复使用相同的roles 属性。只需将roles数组更改为每次在工厂动态创建即可:

    Factory.define :user do |f|
      ...
      f.roles       { ['jobseeker'] }
    end
    Factory.define :employer do |f|
      ...
      f.roles       { ['employer'] }
    end
    

    无论是这样,OR 避免使用&lt;&lt; 或任何更改现有数组/变量的方法,而是使用使用新对象的=。例如

    # should reject undefined roles
    @user.roles = [ "foo" ]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多