【问题标题】:stub random value in rspec with secure_random带有secure_random的rspec中的存根随机值
【发布时间】:2016-11-17 03:40:19
【问题描述】:

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

  1. otp_code - 基本上是使用 secure_random 生成的随机值
  2. otp_verified - 一个布尔值,用于设置是否验证 otp 的状态
  3. otp_expiry_time - 设置 otp 的过期时间,可以通过 rails app 在配置中设置。

这三个也是我数据库的列。

现在在generate_otp 之后,我正在调用active_recordssave 方法来将值保存到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,但没有多大帮助。这是我第一次编写规范,并且对 rspecs 真的没有太多经验。我也研究了官方documentation 的mock 和stub,但我真的很困惑。

更新: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

【问题讨论】:

  • 如果您正在学习一种不同的存根方法,那么链接的问题和答案将没有多大意义。每个测试库(和 RSpec 版本)对方法存根的语法略有不同,因此请注意不要混用在互联网上找到的示例。您问题中的大多数细节(包括想要存根随机数生成器的方法的事实)都是无关紧要的。您能否通过单个 RSpec 测试显示您在哪里,以及您在文档中究竟坚持了什么?此外,选择您想要断言的示例行为非常关键。
  • 实际上这就是问题所在,我不知道如何存根,而是验证该值是否存储在 db 中并分配给 otp_code 列。我在这里感到困惑。
  • 展示你到目前为止所拥有的东西,展示你希望你的测试展示的东西非常重要。
  • 尼尔我已经更新了这个问题。现在我想要测试该值是否分配给otp_code 列,并且还想存根生成的值并确保该值保存在数据库中。

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


【解决方案1】:

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

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

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

【讨论】:

  • 谢谢,我试试看。
  • 嘿,你能告诉我我们如何存根[*('A'..'Z'),*('0'..'9')].sample(8).join这个代码
  • 将该行代码放入辅助方法中,并存根该方法。
猜你喜欢
  • 1970-01-01
  • 2011-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-01
  • 2014-01-12
  • 2011-05-10
相关资源
最近更新 更多