Question

I'm trying to write some tests with RSpec (and 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

Now I get this failures:

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

Whats wrong with my Time expectations?

Solution

Using the timecop gem solves the problem

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
Was it helpful?

Solution

Use 'timecop' gem. This gem handles that for you.

You have a railscast dedicated to this gem: http://railscasts.com/episodes/276-testing-time-web-requests

You could do something like that:

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

Adjust it to your needs.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top