RSpec:时间比较没有通过

时间:2014-03-17 10:26:39

标签: ruby-on-rails rspec ruby-on-rails-4 rspec-rails

我试图用RSpec(和Rails)编写一些测试:

require 'spec_helper'

describe 'API Key' do
  it 'does generates access token' do
    api_key = FactoryGirl.build(:api_key_session)
    expect(api_key.access_token) =~ /\S{32}/
  end

  it 'does expire tomorrow night on session scope' do
    Time.stub(:now)
    api_key = FactoryGirl.build(:api_key_session)
    expect(api_key.expired_at).to eq(Chronic.parse('tomorrow 00:00'))
  end

  it 'does expire in 30 days on api scope' do
    Time.stub(:now)
    api_key = FactoryGirl.build(:api_key_api)
    expect(api_key.expired_at).to eq(Time.new(30.days.from_now))
  end

end

现在我遇到了这个失败:

Failures:

  1) API Key does expire tomorrow night on session scope
     Failure/Error: expect(api_key.expired_at).to eq(Chronic.parse('tomorrow 00:00'))

       expected: 2014-03-18 00:00:00.000000000 +0100
            got: 2014-03-17 15:25:09.149561000 +0100

       (compared using ==)

       Diff:
       @@ -1,2 +1,2 @@
       -2014-03-18 00:00:00 +0100
       +Mon, 17 Mar 2014 15:25:09 CET +01:00

     # ./spec/models/api_key_spec.rb:12:in `block (2 levels) in <top (required)>'

  2) API Key does expire in 30 days on api scope
     Failure/Error: expect(api_key.expired_at).to eq(Time.new(30.days.from_now))
     TypeError:
       no implicit conversion of ActiveSupport::TimeWithZone into Integer
     # ./spec/models/api_key_spec.rb:17:in `initialize'
     # ./spec/models/api_key_spec.rb:17:in `new'
     # ./spec/models/api_key_spec.rb:17:in `block (2 levels) in <top (required)>'

Finished in 0.02742 seconds
3 examples, 2 failures

Failed examples:

rspec ./spec/models/api_key_spec.rb:10 # API Key does expire tomorrow night on session scope
rspec ./spec/models/api_key_spec.rb:15 # API Key does expire in 30 days on api scope

我的时间期望有什么不对?

解决方案

使用timecop gem解决了问题

的Gemfile:

group :test do
  gem 'timecop'
end

spec_helper.rb

config.before(:each) do
  Timecop.return
end

api_key_spec.rb

require 'spec_helper'

describe 'API Key' do

  it 'does generates access token' do
    api_key = FactoryGirl.build(:api_key_session)
    expect(api_key.access_token) =~ /\S{32}/
  end

  it 'does expire tomorrow night on session scope' do
    Timecop.freeze
    api_key = FactoryGirl.build(:api_key_session)
    expect(api_key.expired_at).to eq(Chronic.parse('tomorrow 00:00'))
  end

  it 'does expire in 30 days on api scope' do
    Timecop.freeze
    api_key = FactoryGirl.build(:api_key_api, expired_at: 30.days.from_now)
    expect(api_key.expired_at).to eq(30.days.from_now)
  end

end

1 个答案:

答案 0 :(得分:2)

使用'timecop' gem。这个宝石为你处理。

你有一个专门用于这个宝石的railscast:http://railscasts.com/episodes/276-testing-time-web-requests

你可以这样做:

describe 'API Key' do
  it 'does expire in 30 days on api scope' do
    Timecop.freeze
    api_key = FactoryGirl.build(:api_key_session)
    expect(api_key.expired_at).to eq(30.days.from_now)
  end
end

根据您的需要进行调整。