Сбой сравнения двух объектов ActiveSupport::TimeWithZone

В моем наборе тестов есть неудачный тест.

expected[0]['date'] происходит от SomeModel.first.created_at

В консоли отладки у меня есть следующее:

> expected[0]['date']
=> Tue, 25 Mar 2014 16:01:45 UTC +00:00
> res[0]['date']
=> Tue, 25 Mar 2014 16:01:45 UTC +00:00
> res[0]['date'] == expected[0]['date']
=> false # wtf
> res[0]['date'].class
=> ActiveSupport::TimeWithZone
> expected[0]['date'].class
=> ActiveSupport::TimeWithZone
>

Как это возможно ?

Я пытался воспроизвести эту проблему (я думал, что оператор == в TimeWithZone проверяет ссылку или что-то в этом роде, но нет...):

> t1 = Time.zone.at(0)
=> Thu, 01 Jan 1970 00:00:00 UTC +00:00
> t2 = Time.zone.parse(t1.to_s)
=> Thu, 01 Jan 1970 00:00:00 UTC +00:00
> t1 == t2
=> true
> t1.class
=> ActiveSupport::TimeWithZone
> t2.class
=> ActiveSupport::TimeWithZone

Изменить: больше тестов...

> res[0]['date'].eql?(expected[0]['date'])
=> false
> res[0]['date'].zone
=> "UTC"
> expected[0]['date'].zone
=> "UTC"
> expected[0]['date'].getlocal
=> 2014-03-25 16:01:45 +0000
> res[0]['date'].getlocal
=> 2014-03-25 16:01:45 +0000
> res[0]['date'].hash
=> -3455877575500291788
> expected[0]['date'].hash
=> -3819233736262144515
>
> t1.hash
=> 2279159074362527997
> t2.hash
=> 2279159074362527997

# inspect...
> expected[0]['date'].inspect
=> "Tue, 25 Mar 2014 16:39:01 UTC +00:00"
> res[0]['date'].inspect
=> "Tue, 25 Mar 2014 16:39:01 UTC +00:00"

Похоже, сравнение основано на хеш-объекте. Почему res и expect имеют разные hashes?


person Benjamin Crouzier    schedule 25.03.2014    source источник
comment
Что такое рез? Вы пытались распечатать res.inspect иожидаемый.inspect ?   -  person vdaubry    schedule 25.03.2014
comment
@vdaubry Добавлен осмотр   -  person Benjamin Crouzier    schedule 25.03.2014
comment
Такая же проблема - разобрались?   -  person Kurt Funai    schedule 07.05.2014
comment
Добавил несколько разных ответов о том, как решить эту проблему во время тестирования, не уверен, что какой-либо из них будет полезен для всех, но я смог решить свою проблему, следуя ответу № 2 (Spring/Rspec).   -  person Kurt Funai    schedule 08.05.2014


Ответы (1)


Ответ №1 rake db:test:prepare

Сначала попробуйте удалить тестовую базу данных и создать ее заново, а затем запустить rake db:test:prepare. Это решило эту проблему для меня в прошлом. Я знаю, что это немного неубедительный ответ, но стоит попробовать.

Ответ №2 Сопоставители Spring + Rspec + Shoulda

Если возникла эта проблема после установки Spring, ознакомьтесь с этой веткой Github, которая может привести к сбою тестов: https://github.com/rails/spring/issues/209

Эта проблема начала возникать у меня только после добавления Spring в мой проект. Добавление gem 'shoulda', require: false и ручное добавление require 'shoulda/matchers' к моему spec_helper.rb решило проблемы

Ответ №3 Timecop

Если у вас все еще есть проблемы, проверьте драгоценный камень Timecop и остановите сравнение времени вокруг даты. https://github.com/travisjeffery/timecop

person Kurt Funai    schedule 07.05.2014
comment
Кажется, что ошибка возникает из-за сравнения результата #to_f, который я обошел, используя только выровненные метки времени с моими тестами, такими как, например. 1.day.ago.noon Я предполагаю, что timecop делает что-то подобное. - person lab419; 24.03.2016