【问题标题】:FactoryGirl Sequences aren't workingFactoryGirl 序列不起作用
【发布时间】:2013-10-07 23:49:53
【问题描述】:

我完全按照documentation 中所说的做,但仍然收到验证错误:

验证失败:电子邮件已被占用

FactoryGirl.define do
  sequence :email do |n|
    "test#{n}@factory.com"
  end

  factory :user do
    email           
    password              '12345678'
    password_confirmation '12345678'
    goal_id               1
    experience_level_id   1
    gender                'Female'
  end
end

有人知道我在这里做错了什么吗?

编辑:

这是失败的规范。如果您取消注释主题块并注释掉 FactoryGirl 内容,它工作正常。我正在尝试改用 FactoryGirl。

require 'spec_helper'
require 'cancan/matchers'

describe User do
  # subject(:user) do
  #   Program.create!(name: 'test', gender: 'Female', goal_id: '1', experience_id: '1')
  #   User.create!(email: 'test@test.com', password: '12345678', password_confirmation: '12345678', goal_id: '1', experience_level_id: '1', gender: 'Female')
  # end
  FactoryGirl.create(:program)
  puts FactoryGirl.create(:user).inspect

  it "should be assigned a program when it's created" do
    user.programs.should exist
  end

  it "should be valid with a name, goal, password, password_confirmation, experience_level, and gender" do
    user.should be_valid
  end

  it { should respond_to(:programs) }
  its('programs.last.name') {should == 'Test'}

  it "should be assigned imperial as the default measurement_units" do
    user.measurement_units.should eq("imperial") 
  end

  it 'validates presence of gender, goal_id, and experience_level_id' do
    user = User.new(gender: nil)
    user.should validate_presence_of(:gender)
    user.should validate_presence_of(:goal_id)
    user.should validate_presence_of(:experience_level_id)
  end
end

编辑 2:

我已根据其中一个答案的建议更新了我的规范,所以现在我的规范运行了,但我得到一个失败的测试并出现验证错误。这是更新的代码:

describe User do
  subject(:user) do
  #   Program.create!(name: 'test', gender: 'Female', goal_id: '1', experience_id: '1')
  #   User.create!(email: 'test@test.com', password: '12345678', password_confirmation: '12345678', goal_id: '1', experience_level_id: '1', gender: 'Female')
    FactoryGirl.create(:program)
    FactoryGirl.create(:user)
  end

  it "should be assigned a program when it's created" do
    user.programs.should exist
  end

以及来自失败测试的消息:

Failures:

  1) User should be assigned a program when it's created
     Failure/Error: FactoryGirl.create(:user)
     ActiveRecord::RecordInvalid:
       Validation failed: Email has already been taken
     # ./spec/models/user_spec.rb:9:in `block (2 levels) in <top (required)>'
     # ./spec/models/user_spec.rb:13:in `block (2 levels) in <top (required)>'

有什么想法吗?

【问题讨论】:

  • 您的序列设置看起来不错。您可以通过在规范中包含 puts FactoryGirl.create(:user).inspect 来验证这一点。您的用户表是否在测试数据库中的 rspec 运行之间意外持久化?您是否在某个地方使用dup 复制现有用户,然后尝试调用save! 而不是save
  • 这真的让我很困惑。我的用户表在测试数据库中的 rspec 运行之间持续存在,但仅在我使用 FactoryGirl 时才存在。当我通过 subject(:user) do; User.create!(email: 'test@test.com', password: '12345678', password_confirmation: '12345678', goal_id: '1', experience_level_id: '1', gender: 'Female'); end 简单地创建用户时,它工作正常,如果我运行两次测试,我不会收到验证错误。
  • 你能分享你失败的规范吗?

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


【解决方案1】:

您不能像这样在测试类的中间创建工厂实例。 FactoryGirl 是您之前在代码中的实例化的替代品 - 离开 subject 块,只需将两个 create 行替换为 FactoryGirl 调用。

(更好的是,它们应该是 let 块而不是 subject 块,但这是另一回事)

如果你不是在 Rspec 知道的上下文中做事,它就无法事后清理。

【讨论】:

  • @Arel 这就是我的怀疑。另见stackoverflow.com/questions/3497135/…
  • 谢谢!我正在尝试编写更好的测试,还有很多东西要弄清楚。您是否有关于使用 let 块而不是主题块的文档的链接?我是否像使用主题一样使用 let ?
  • 没关系,我能够通过除一项测试之外的所有测试,而失败的测试显示相同的验证错误。不过,我已经走得更远了。
  • 刚刚用更新的信息更新了我的问题。感谢您的帮助!
  • 所以我重置了测试数据库,验证错误消失了。
【解决方案2】:

您的 Gemfile 中有什么?我使用它取得了更好的成功

  gem 'factory_girl_rails', :group => :test

而不是将其列在“group :development, :test do”部分。

【讨论】:

  • 我在开发/测试中有它。我会试着移动它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-11-14
  • 2012-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-21
相关资源
最近更新 更多