rspec中的stub随机值与secure_random

时间:2016-07-14 09:28:46

标签: ruby-on-rails ruby unit-testing rspec rubygems

我正在尝试为我的gem编写规范,它会生成otp并将其保存在db中。现在我正在为它编写规范。基本上我有三种方法generate_otp!regenerate_otp!verify_otp(otp)generate_otp!所做的是它调用方法generate_otp,其中包含三个变量

  1. otp_code - 基本上是使用secure_random
  2. 生成的随机值
  3. otp_verified - 一个布尔值,用于设置是否验证otp的状态
  4. otp_expiry_time - 设置otp的到期时间,可由配置中的rails app设置。
  5. 这三个都是我的数据库的列。

    现在generate_otp后我调用active_records save方法将值保存到db。

    现在进行测试我在:memory:中使用并在表中存储值。经过测试我正在丢弃数据库。现在我没有得到如何存根随机生成的值并测试值是否已分配给所有三列,即otp_codeotp_verifiedotp_expiry_time

    以下是我需要测试的方法的代码。

    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
    

    对此有何帮助?我也检查了这个question,但没有多大帮助。这是我第一次编写规范,并且真的没有那么多的rspec经验。我还研究了模拟和存根的官方documentation,但我真的很困惑。

    更新:otp_spec代码

    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
    

1 个答案:

答案 0 :(得分:9)

SecureRandom中删除rspec方法的直接方法如下:

before { allow(SecureRandom).to receive(:hex).with(4).and_return('abcd1234') }

然后,您可以检查'abcd1234'是否存储在数据库中。为了保持测试DRY,您可能还希望将其作为变量引用,例如, let(:random_value) { 'abcd1234' }