Reputation: 4952
I have a model, which is using attr_encrypted
gem to encrypt the password.
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
I am learning to write test cases and my factory for the above looks like this:
FactoryBot.define do
factory :credential do
user_name { "rmishra" }
user_pass { "secret" }
credential_type { "linux" }
encryption_key { "abcdefghijklmnopqrstuvw123456789" }
end
end
My spec file looks like:
RSpec.describe Credential, type: :model do
let(:credential) { create(:credential) }
...
end
How do I stub encryption_key
method in factory definition, which is getting used at the time of create
?
Upvotes: 1
Views: 3140
Reputation: 760
Since encryption_key
is not an attribute on your model, you can't configure it in your factory.
encryption_key
is called automatically by the attr_encrypted
gem when you assign user_pass
to a Credential
object. In this case that's done by the factory.
I would move the logic in your encryption_key
method into a class to facilitate testing:
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
Then, in my test, I would stub the 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
Encapsulating your encryption key generation logic into a separate object decouples it from your model, allowing you to easily test that logic without having to create a Credential
object.
Upvotes: 2