在控制器方法中,当向该用户发送激活电子邮件时,我将用户的变量activation_sent_at
设置为等于Time.zone.now
。在开发服务器上,这似乎有效(尽管我的应用程序中的时间表达式在我的计算机的本地时间落后2小时)。
我想要包含一个集成测试,用于测试activation_sent_at
是否确实正确设置。所以我加入了这一行:
assert_equal @user.activation_sent_at, Time.zone.now
然而,这会产生错误:
No visible difference in the ActiveSupport::TimeWithZone#inspect output.
You should look at the implementation of #== on ActiveSupport::TimeWithZone or its members.
我认为它建议在我的测试中使用Time.zone.now
的另一个表达式。我查看了不同的来源,包括http://api.rubyonrails.org/classes/ActiveSupport/TimeWithZone.html,但我不知道该怎么做。可能导致此错误的任何建议?
其他信息:添加puts Time.zone.now
和puts @stakeholder.activation_sent_at
确认两者相同。不确定是什么导致失败/错误。
答案 0 :(得分:24)
问题是两个日期彼此非常接近但不一样。您可以使用assert_in_delta
assert_in_delta @user.activation_sent_at, Time.zone.now, 1.second
对于 RSpec ,类似的方法是使用be_within
:
expect(@user.activation_sent_at).to be_within(1.second).of Time.zone.now
答案 1 :(得分:2)
问题是你的时间非常接近但不完全相同。它们可能会在几分之一秒内消失。
这类问题的一个解决方案是名为timecop的测试宝石。它使您能够模拟Time.now,以便它临时返回可用于比较的特定值。
答案 2 :(得分:1)
原因是因为Time.now
或Time.zone.now
包含毫秒(当您执行简单的put
来打印不显示毫秒的时间时)。但是,当您在数据库中保留时间戳时,除非将db字段配置为存储毫秒,否则这些毫秒可能会丢失。因此,当您从数据库读取值时,它将不包含毫秒,因此时间略有不同。
一种解决方案是从Time.now中删除毫秒。您可以像Time.now.change(usec: 0)
这样来做。这应该可以修复测试中的错误。