You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Rails中Timecop.travel测试返回false而非true问题求助

问题分析

你的测试失败的核心原因是Timecop修改当前时间后,24.hours.ago的基准也跟着变了,导致你的时间比较逻辑完全搞反了。

我们拆解下测试里的时间线就清楚了:

  • 你用Timecop.travel 2.days.ago把系统当前时间“穿越”到了2天前
  • 创建的Message的created_at就是这个2天前的时刻
  • 当你计算24.hours.ago时,这个值是基于被Timecop修改后的当前时间(也就是2天前),算下来就是2天前 - 24小时 = 3天前
  • 最后判断time_created < 24.hours.ago → 相当于判断“2天前 < 3天前”,这显然是false,和你预期的true完全相反
解决方案

这里有几种清晰的修复方式,你可以根据习惯选择:

方式1:修正比较逻辑(最简单)

直接计算消息创建时间与当前时间的差值,判断是否超过24小时,这样不管Timecop怎么改时间,逻辑都不会乱:

test "messenger tag is more than 24 hours" do
  Timecop.travel 2.days.ago
  account = accounts(:messenger_v2)
  contact_d = Contact.create! account: account, name: 'Mr Right', phone_number: nil, external_id: '155581474881005', contact_type: 'MessengerV2', source: 'Inbound', is_registered: true, primary_contact: true
  conversation = Conversation.create! contact: contact_d, account: account, status: 'Open', unread: true, conversation_type: 'Private'
  Message.create! contact: contact_d, message_type: 'Text', text: 'I have some enquries', direction: 'IN', account: account, conversation: conversation, external_id: "in_a#{Time.now.to_i.to_s}"
  msg = conversation.messages.incoming
  time_created = msg.last.created_at
  # 改成计算时间差是否大于24小时
  messenger_tags = (Time.now - time_created) > 24.hours
  assert_equal true, messenger_tags
end

方式2:调整Timecop的使用逻辑(更贴合业务场景)

先穿越到过去创建消息,再回到当前时间做判断,完全模拟真实业务中“消息已超过24小时”的场景:

test "messenger tag is more than 24 hours" do
  account = accounts(:messenger_v2)
  contact_d = Contact.create! account: account, name: 'Mr Right', phone_number: nil, external_id: '155581474881005', contact_type: 'MessengerV2', source: 'Inbound', is_registered: true, primary_contact: true
  conversation = Conversation.create! contact: contact_d, account: account, status: 'Open', unread: true, conversation_type: 'Private'
  
  # 穿越到25小时前创建消息,确保超过24小时阈值
  Timecop.travel(25.hours.ago) do
    Message.create! contact: contact_d, message_type: 'Text', text: 'I have some enquries', direction: 'IN', account: account, conversation: conversation, external_id: "in_a#{Time.now.to_i.to_s}"
  end
  
  # 回到当前时间,判断消息是否早于24小时前
  msg = conversation.messages.incoming
  time_created = msg.last.created_at
  messenger_tags = time_created < 24.hours.ago
  assert_equal true, messenger_tags
end

方式3:手动设置消息创建时间

如果不想用Timecop的复杂穿越,也可以直接给Message指定created_at属性:

test "messenger tag is more than 24 hours" do
  account = accounts(:messenger_v2)
  contact_d = Contact.create! account: account, name: 'Mr Right', phone_number: nil, external_id: '155581474881005', contact_type: 'MessengerV2', source: 'Inbound', is_registered: true, primary_contact: true
  conversation = Conversation.create! contact: contact_d, account: account, status: 'Open', unread: true, conversation_type: 'Private'
  # 直接把消息创建时间设为24小时1分钟前,确保超过阈值
  Message.create! contact: contact_d, message_type: 'Text', text: 'I have some enquries', direction: 'IN', account: account, conversation: conversation, external_id: "in_a#{Time.now.to_i.to_s}", created_at: 24.hours.ago + 1.minute
  msg = conversation.messages.incoming
  time_created = msg.last.created_at
  messenger_tags = time_created < 24.hours.ago
  assert_equal true, messenger_tags
end

内容的提问来源于stack exchange,提问作者Sista-Night

火山引擎 最新活动