RSpec:工厂机器人定义文件中的方法存根

问题描述 投票:0回答:1

我有一个模型,它使用attr_encrypted gem来加密密码。

class Credential < ApplicationRecord
  validates :user_name, presence: true
  enum credential_type: { windows: 1, linux: 2 }

  attr_encrypted :user_pass, key: :encryption_key

  def encryption_key
    # Some complex logic
  end
end

我正在学习编写测试用例,我的工厂如上所示:

FactoryBot.define do
  factory :credential do
    user_name { "rmishra" }
    user_pass { "secret" }
    credential_type { "linux" }
    encryption_key { "abcdefghijklmnopqrstuvw123456789" }
  end
end

我的spec文件看起来像:

RSpec.describe Credential, type: :model do
  let(:credential) { create(:credential) }
  ...
end

如何在工厂定义中存根encryption_key方法,这在create时被使用?

ruby-on-rails rspec factory-bot attr-encrypted
1个回答
0
投票

由于encryption_key不是您模型的属性,因此您无法在工厂中对其进行配置。

当你将encryption_key分配给attr_encrypted物体时,user_pass会被Credential宝石自动调用。在这种情况下,由工厂完成。

我会将你的encryption_key方法中的逻辑移动到一个类中以便于测试:

class Credential < ApplicationRecord
  validates :user_name, presence: true
  enum credential_type: { windows: 1, linux: 2 }

  attr_encrypted :user_pass, key: :encryption_key

  def encryption_key
    EncryptionKeyGenerator.generate # or whatever name makes more sense
  end
end

然后,在我的测试中,我会将EncryptionKeyGenerator存根:

RSpec.describe Credential, type: :model do
  let(:credential) { create(:credential) }
  let(:encryption_key) { "abcdefghijklmnopqrstuvw123456789" }

  before do
    allow(EncryptionKeyGenerator).to receive(:generate).and_return(encryption_key)
  end

  ...
end

将加密密钥生成逻辑封装到单独的对象中将其与模型分离,使您可以轻松地测试该逻辑,而无需创建Credential对象。

© www.soinside.com 2019 - 2024. All rights reserved.