Rails TimeHelpers travel_to with nanosecond not working

Viewed 298

In my code I have Time.current.strftime('%Y%m%d%H%M%S%6N') and to test that I used the Rails TimeHelpers #travel_to method.

in the tests:

travel_to Time.local(2015, 2, 2, 11, 14, 30.123456) do
  ...
end

The problem is that Time.current.strftime('%Y%m%d%H%M%S%6N') returns 000000 for nanoseconds when it should be 123456.

Is there a work around? I am trying not to use TimeCop gem at the moment.

1 Answers

Unfortunately, Rails' travel_to truncates the value to seconds. From the docs:

Note that the usec for the time passed will be set to 0 to prevent rounding errors with external services, like MySQL (which will round instead of floor, leading to off-by-one-second errors).

As a workaround you could change your code to accept an explicit time with current time as its default:

def your_method(time = Time.current)
  time.strftime('%Y%m%d%H%M%S%6N')
end

And in your tests:

describe '#your_method' do
  context 'with an explicit time value' do
    let(:time) { Time.local(2015, 2, 2, 11, 14, 30.123456) }

    it 'generates the corresponding timestamp' do
      expect(your_method(time)).to eq('20150202111430123456')
    end
  end

  context 'without argument' do
    around do |example|
      travel_to(Time.local(2015, 2, 2, 11, 14)) { example.run }
    end

    it 'generates the current timestamp' do
      expect(your_method).to eq('20150202111400000000')
    end
  end
end
Related