I am trying to write specs for my gem, which generates otp and saves it in db. Now i am writing specs for it. so basically i have three methods generate_otp!
, regenerate_otp!
, verify_otp(otp)
. what generate_otp!
does is it calls a method generate_otp
which contains three variables
otp_code
- basically a random value generated using secure_randomotp_verified
- a boolean value to set the status whether otp is verified or nototp_expiry_time
- sets expiry time for otp which can be set by rails app in configuration.these all three are columns of my db also.
Now after generate_otp
i am calling active_records
's save
method to save values to db.
Now for testing i am using in :memory:
and storing values in table. after testing i am dropping the db. Now i am not getting how to stub the randomly generated value and test whether value is assigned or not to all three columns, i.e, otp_code
, otp_verified
, otp_expiry_time
.
Here is code for my methods which i need to test.
def generate_otp
self.otp_verified = false
self.otp_expiry_time = OtpGenerator::configuration.otp_expiry_time
self.otp_code = SecureRandom.hex(4)
end
def generate_otp!
generate_otp
save
end
Any help with this ? I have also checked this question, but not much helpful. It's first time i am writing specs and really don't have that much experience with rspecs. I have also studied the official documentation for mock and stub, but i am really getting confused.
update : otp_spec code
require 'spec_helper'
describe OtpGenerator do
let(:user) { build_mock_class.new() }
before(:all) { create_table }
after(:all) { drop_table }
describe '#generate_otp' do
it 'generate otp and save it' do
user.generate_otp!
end
end
describe '#regenerate_otp' do
it 'regenerate otp and save it' do
end
end
describe '#verify_otp' do
it 'verifies otp' do
end
end
def build_mock_class
Class.new(ActiveRecord::Base) do
self.table_name = 'mock_table'
include OtpGenerator
end
end
def create_table
ActiveRecord::Base.connection.create_table :mock_table do |t|
t.string :otp_code
t.boolean :otp_verified
t.datetime :otp_expiry_time
end
end
def drop_table
ActiveRecord::Base.connection.drop_table :mock_table
end
end
A direct approach to stubbing out the SecureRandom
method in rspec
would be as follows:
before { allow(SecureRandom).to receive(:hex).with(4).and_return('abcd1234') }
You can then check that 'abcd1234'
is stored in the database. In order to keep the test DRY, you may also wish to reference this as a variable, e.g. let(:random_value) { 'abcd1234' }
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With