Gui*_*rme 12 datetime rspec ruby-on-rails
Rails 支持DateTime纳秒分辨率,但我注意到这取决于运行应用程序的机器。
在我运行 Mojave 的 MacBook 上,Time.zone.now.strftime("%N")将始终输出以 , 结尾的 9 位数字000(例如"122981000")。这意味着在Mac上,分辨率被限制在微秒尺度。
然而,在 Linux 上,相同的命令返回一个具有完整纳秒分辨率的数字(例如"113578523")。
当我使用rspec并且需要比较一些DateTime值时,我的问题就出现了。
当我在 Mac 上进行开发时,测试完美地通过了,但是当我们的 CI (Travis) 运行相同的测试时,它会失败,如下所示:
expected: 2019-04-09 19:14:27.214939637 -0300
got: 2019-04-09 19:14:27.214939000 -0300
Run Code Online (Sandbox Code Playgroud)
这里的问题是我们的数据库 Postgres 仅限于微秒,就像我的 Mac 一样,它不会失败。我将其存储DateTime在数据库中,然后读回并与内存中的内容进行比较。DB 四舍五入到微秒,因此比较失败。
是否可以强制 Rails 以微秒精度运行?
我的目的是不需要在每个测试中手动舍入或截断时间戳。
我过去曾经遇到过这个问题,新创建的 ActiveRecord 对象在内存中创建/更新的字段上具有 9 位精度(在 Travis linux VM 上),这与存储在 Postgres 中的内容(6 位数字)不同)。我遇到了同样的问题,这些测试在本地(macOS)通过,但在 CI 构建中失败。
在过去,我修改了规范来强制重新加载对象,该对象有效,但正如您所强调的那样,它很丑陋,因为您必须为每个测试执行此操作。最近,我再次遇到了同样的问题,但这一次是我创建的服务对象无法“重新加载”,所以我开始尝试寻找更好的解决方案。
它并不完全理想,因为它需要猴子修补 Time 类,但是它有效!
module ForceTimePrecision
def now
super.round(6)
end
end
Time.singleton_class.send(:prepend, ForceTimePrecision)
Run Code Online (Sandbox Code Playgroud)
修补 Time 单例的机制(因为我不能直接覆盖 Time.now)基于这个答案/sf/answers/4246590421/
| 归档时间: |
|
| 查看次数: |
1866 次 |
| 最近记录: |