datetime - 轨道 4 : `Time.now.utc.iso8601` sometimes off by 1 second in specs

标签 datetime ruby-on-rails-4 utc iso

我正在使用 JSON 构建 Rails 4 API,并返回 updated_at 属性作为 ISO 格式的 UTC 时区。

记录.updated_at # => 2015-04-14 10:01:37 -0400 record.updated_at.utc.iso8601 # => "2015-04-14T14:01:37Z"

但是,当 updated_at 关闭 1 秒时,我的 rspec 规范偶尔会间歇性失败:

# records_controller_spec.rb
RSpec.describe RecordsController do
  describe "update - PUT #update" do
    record = FactoryGirl::create(:record, value: "original")
    record_params = { value: "updated" }

    xhr :put, api_v1_record_path(record), record_params

    # Uses ActiveModelSerializer
    # json = JSON.parse(response.body)
    expect(response).to have_http_status(:ok)
    expect(json["updated_at"]).to eq(record.updated_at.utc.iso8601)
  end
end

# app/serializers/record_serializer.rb
class RecordSerializer < ActiveModel::Serializer
  attributes :id, :created_at, :updated_at, :value

  def created_at
    object.created_at.utc.iso8601
  end

  def updated_at
    object.updated_at.utc.iso8601
  end
end

# Running rspec...
Failure/Error: expect(json["updated_at"]).to eq(record.updated_at.utc.iso8601)

       expected: "2015-04-14T13:59:35Z"
            got: "2015-04-14T13:59:34Z"

       (compared using ==)

如果我再次运行规范,它会通过很多次,然后随机地会再次失败,时间比较再次偏离 1 秒。

是否有办法确保规范中日期时间转换的一致性?

最大的问题是,如果rspec套件随机失败(如果规范恰好在给定秒的范围内),则使用 CI 服务器的自动部署将随机失败。

最佳答案

解决方案是我在更新操作后没有重新加载对象,因此我得到了一个“脏”updated_at,并且它偶尔会失败,因为测试发生得太快了。

RSpec.describe RecordsController do
  describe "update - PUT #update" do
    record = FactoryGirl::create(:record, value: "original")              
    record_params = { value: "updated" }

    # record.updated_at => "2015-06-23 22:30:00"

    xhr :put, api_v1_record_path(record), record_params

    # record.updated_at => "2015-06-23 22:30:00"

    # SOLUTION CODE (notice timestamp updated below)
    record.reload

    # record.updated_at => "2015-06-23 22:30:01"


    # Uses ActiveModelSerializer
    # json = JSON.parse(response.body)
    expect(response).to have_http_status(:ok)
    expect(json["updated_at"]).to eq(record.updated_at.utc.iso8601)
  end
end

我发现对于任何更改/更新记录的规范,我必须重新加载对象才能获取正确的时间戳值。我没有比这更好的通用方法了。

如果有人有更干净的解决方案,请随时发布,我会接受它而不是我的。

关于datetime - 轨道 4 : `Time.now.utc.iso8601` sometimes off by 1 second in specs,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29629592/

相关文章:

php - 添加 2 年至今

ruby-on-rails - Rails-获取当前星期和月份的开始和结束日期

php - 日期选择框值转换为 SQL 数据库日期类型值

ruby-on-rails - Capybara::ElementNotFound,但它在那里

ruby-on-rails - 如果验证失败,请在重新加载时保留更改

Python 时间库 : how do I preserve dst with strptime and strftime

javascript - 您可以将 new Date().toUTCString() 更改为自 1970 年 1 月 1 日以来的毫秒数吗?

PHP : SQL STATE 22007 when inserting date or datetime

ruby-on-rails - Rspec 未定义的局部变量或方法 root_path

c# - AspNet Core 中 UTC 的 Http 查询参数