【问题标题】:Rails 5 - Errors with FactoryGirlRails 5 - FactoryGirl 的错误
【发布时间】:2016-12-23 20:11:28
【问题描述】:

我遇到了以下问题。

我正在使用带有以下变量的 Factory Girl Rails:

FactoryGirl.define do
  conta_destino_matriz = FactoryGirl.create(:conta_pessoa_fisica, saldo: 0)
  conta_origem_filial = FactoryGirl.create(:conta_pessoa_fisica, saldo: 1000, ancestry: conta_destino_matriz.id)

  codigo_transacional =  TransacaoHelper::Gerador.codigo_alphanumerico(
    tipo: 'transferencia', conta_origem_id: conta_origem_filial.id, conta_destino_id: conta_destino_matriz.id
  )

  factory :transacao_transferencia_matriz, class: Transacao do
    tipo { 'transferencia' }
    valor { '250' }
    conta_origem_id { conta_origem_filial.id }
    conta_destino_id { conta_destino_matriz.id }

    trait :campos_completos do
      codigo_transacional { codigo_transacional }
      conta_origem_valor_antes_transacao { conta_origem_filial.saldo }
      conta_destino_valor_antes_transacao { conta_destino_matriz.saldo }
      estornado { false }
      codigo_transacional_estornado { nil }
    end
  end
end

conta_destino_matriz 在工厂名称定义之外声明。这是必需的,因为来自工厂的两个属性需要具有来自某些关联的两个值,例如:

conta_destino_id                    { conta_destino_matriz.id }
conta_destino_valor_antes_transacao { conta_destino_matriz.saldo }

而另一个测试使用了具有相同关联工厂 conta_pessoa_fisica 的工厂:

FactoryGirl.define do
  conta_origem_hierarquia_igual = FactoryGirl.create(:conta_pessoa_fisica, saldo: 1000)
  conta_destino_hierarquia_igual = FactoryGirl.create(:conta_pessoa_fisica, saldo: 0, ancestry: conta_origem_hierarquia_igual.id)
  codigo_transacional_hierarquia_igual =  TransacaoHelper::Gerador.codigo_alphanumerico(
      tipo: 'transferencia', conta_origem_id: conta_origem_hierarquia_igual.id, conta_destino_id: conta_destino_hierarquia_igual.id
  )

  conta_origem_hierarquia_diferente = FactoryGirl.create(:conta_pessoa_fisica, saldo: 1000)
  conta_destino_hierarquia_diferente = FactoryGirl.create(:conta_pessoa_fisica, saldo: 0)

  factory :transacao_transferencia_hierarquia, class: Transacao do
    tipo { 'transferencia' }
    valor { '250' }
    conta_origem_id { conta_origem_hierarquia_igual.id }
    conta_destino_id { conta_destino_hierarquia_igual.id }

    trait :campos_completos do
      codigo_transacional { codigo_transacional_hierarquia_igual }
      conta_origem_valor_antes_transacao { conta_origem_hierarquia_igual.saldo }
      conta_destino_valor_antes_transacao { conta_destino_hierarquia_igual.saldo }
      estornado { false }
      codigo_transacional_estornado { nil }
    end

    trait :diferente do
      conta_origem_id { conta_origem_hierarquia_diferente.id }
      conta_destino_id { conta_destino_hierarquia_diferente.id }
    end
  end
end

这就是关联:

FactoryGirl.define do
  factory :pessoa_fisica do
    cpf { Faker::Number.number(11) }
    nome { Faker::Name.name }
    data_nascimento { Date.today.strftime('%Y-%m-%d') }

    factory :pessoa_fisica_invalida do
      id { 0 }
      cpf { Faker::Number.number(10) }
      nome { '' }
      data_nascimento { (DateTime.now + 1.day).strftime('%Y-%m-%d') }
    end
  end
end

我在 :pessoa_fisica 类的“nome”属性中发生的错误已被存储。该字段必须是唯一的,并且只能是字符。

nome { Faker::Name.name }

所以,当我的测试运行并调用 :transacao_transferencia_matriz 和 :transacao_transferencia_hierarquia 时,有时我会收到一条错误提示

`raise_validation_error': A validation failed: Nome is already taken (ActiveRecord::RecordInvalid)

更糟糕的是,我有时会收到此错误。

【问题讨论】:

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


    【解决方案1】:

    您工厂中的以下内容不保证唯一性:

    nome { Faker::Name.name }
    

    Faker 从有限的集合中生成名称,有时会返回数据库中已经存在的名称。由于您对模型进行了验证检查,因此它当然失败了。

    为保证名称中的唯一性使用顺序,在您的工厂内:

    sequence(:nome) {|n| "#{Faker::Name.name} #{n}" }
    

    理想情况下,您还应该确保每次测试的数据库都处于干净状态 - 查看 database cleaner gem

    【讨论】:

    • 我来只是为了完成这个主题。真正的问题是我预计 FactoryGirl 会清理数据库,但它没有。所以,错误就是这样。 Faker 对有时与数据库匹配的名称有限制,我得到了错误。谢谢你的提示。我也将使用序列,但在这种情况下我将使用字母,因为该字段不能有数字。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-14
    • 1970-01-01
    相关资源
    最近更新 更多