如何使用rspec测试类方法

时间:2018-03-28 15:50:01

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

您好我正在使用ruby-2.5.0和rails 5.0处理RoR项目。我有一个模型forgot_password,其中定义了一个类方法来创建一个记录,如下所示: -

<div class="org_container" id="org1" onclick="orgClick(this.id);">

  <div class="org_name">

    <p align="center">Org 1</p>

  </div>

  <div class="org_logo">

    <img src="http://server3.sulmaxcp.com/logo_unavailable.svg" width="100px" height="100px" ondragstart="return false;">

  </div>

  <div class="org_info">

    <p></p>

  </div>

</div>

<div class="org_container" id="org2" onclick="orgClick(this.id);">

  <div class="org_name">

    <p align="center">Org 2</p>

  </div>

  <div class="org_logo">

    <img src="http://server3.sulmaxcp.com/logo_unavailable.svg" width="100px" height="100px" ondragstart="return false;">

  </div>

  <div class="org_info">

    <p></p>

  </div>

</div>

<div class="org_container" id="org3" onclick="orgClick(this.id);">

  <div class="org_name">

    <p align="center">Org 3</p>

  </div>

  <div class="org_logo">

    <img src="http://server3.sulmaxcp.com/logo_unavailable.svg" width="100px" height="100px" class="noselect">

  </div>

  <div class="org_info">

    <p></p>

  </div>

</div>

我想使用stub或factory_girl gem为它编写单元测试。

forgot_password.rb
# frozen_string_literal: true

class ForgotPassword < ApplicationRecord
  before_create :create_token

  def self.create_record
    self.create!(expiry: Time.zone.now +
                 ENV['VALIDITY_PERIOD'].to_i.hours)
  end

  private

  def create_token
    self.token = SecureRandom.urlsafe_base64(nil, false)
  end
end

但它的投掷错误spec/models/forgot_password_spec.rb # frozen_string_literal: true require 'rails_helper' describe ForgotPassword do let(:forgot_password) do described_class.new() end describe 'create_record' do context 'with forgot_password class' do subject { forgot_password.create_record.class } it { is_expected.to eq ForgotPassword } end end end 请帮助我如何测试我的模型。提前谢谢。

2 个答案:

答案 0 :(得分:0)

您可以直接针对described_class进行测试:     需要'rails_helper'

describe ForgotPassword do
  context 'with forgot_password class' do
    subject { described_class }

    it { is_expected.to eq ForgotPassword }
  end
end

答案 1 :(得分:0)

你所写的是一个工厂方法(一个返回实例的类方法)你应该调用它并写下关于返回的实例的期望:

describe ForgotPassword do
  describe ".create_record" do
    subject { described_class.create_record! }
    it { is_expected.to be_an_instance_of(described_class) }
    it "sets the expiry time to a time in the future" do
      expect(subject.expiry > Time.now).to be_truthy
    end
  end
end

但是,如果你真正想要做的是设置一个计算的默认值,那么就会有一种不那么笨重的方式:

class ForgotPassword < ApplicationRecord
  after_initialize :set_expiry!

  private

  def set_expiry!
    self.expiry(expiry: Time.zone.now).advance(hours: ENV['VALIDITY_PERIOD'].to_i)
  end
end

或者使用Rails 5:

class ForgotPassword < ApplicationRecord
  attribute :expiry, :datetime, 
    ->{ Time.zone.now.advance(hours: ENV['VALIDITY_PERIOD'].to_i) }
end

您可以通过以下方式进行测试:

describe ForgotPassword do
  let(:forgot_password){ described_class.new }
  it "has a default expiry" do
    expect(forgot_password.expiry > Time.now).to be_truthy
  end
end