lob*_*ati 23 time rspec ruby-on-rails
我正在使用Time in Rails并使用以下代码设置项目的开始日期和结束日期:
start_date ||= Time.now
end_date = start_date + goal_months.months
Run Code Online (Sandbox Code Playgroud)
然后我克隆对象,我正在编写rspec测试以确认副本中的属性是否匹配. 结束日期匹配:
original[end_date]: 2011-08-24 18:24:53 UTC
clone[end_date]: 2011-08-24 18:24:53 UTC
Run Code Online (Sandbox Code Playgroud)
但规格在开始日期给我一个错误:
expected: Wed Aug 24 18:24:53 UTC 2011,
got: Wed, 24 Aug 2011 18:24:53 UTC +00:00 (using ==)
Run Code Online (Sandbox Code Playgroud)
很明显日期是相同的,只是格式不同.它们最终是如何在数据库中以不同方式存储的,以及如何使它们匹配?我已经尝试使用DateTime以及相同的结果.
更正: 结束日期也不匹配.他们打印出相同的,但也有rspec错误.当我打印出开始日期和结束日期时,值以不同的格式出现:
start date: 2010-08-24T19:00:24+00:00
end date: 2011-08-24 19:00:24 UTC
Run Code Online (Sandbox Code Playgroud)
cut*_*ion 50
这通常发生是因为rspec尝试匹配不同的对象:例如Time和DateTime.此外,可比较的时间可能有点不同,持续几毫秒.
在第二种情况下,正确的方法是使用存根和模拟.另见TimeCop gem
在第一种情况下,可能的解决方案是比较时间戳:
actual_time.to_i.should == expected_time.to_i
Run Code Online (Sandbox Code Playgroud)
我使用简单的匹配器来处理这种情况:
# ./spec/spec_helper.rb
#
# Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|f| require f}
#
#
# Usage:
#
# its(:updated_at) { should be_the_same_time_as updated_at }
#
#
# Will pass or fail with message like:
#
# Failure/Error: its(:updated_at) { should be_the_same_time_as 2.days.ago }
# expected Tue, 07 Jun 2011 16:14:09 +0300 to be the same time as Mon, 06 Jun 2011 13:14:09 UTC +00:00
RSpec::Matchers.define :be_the_same_time_as do |expected|
match do |actual|
expected.to_i == actual.to_i
end
end
Run Code Online (Sandbox Code Playgroud)
rob*_*okl 23
您应该模拟现在的Time方法,以确保它始终与规范中的日期匹配.你永远不知道延迟何时会使规范因为几毫秒而失败.这种方法还可以确保实际代码和规范上的时间相同.
如果您使用的是默认的rspec mock lib,请尝试执行以下操作:
t = Time.parse("01/01/2010 10:00")
Time.should_receive(:now).and_return(t)
Run Code Online (Sandbox Code Playgroud)
Dre*_*ewB 21
我完全赞同以前关于存在Time.now的答案.也就是说这里还有另外一件事.当您比较数据库中的日期时间时,您会丢失一些可以在ruby DateTime obj中的派系时间.在Rspec中以这种方式比较日期的最佳方法是:
database_start_date.should be_within(1).of(start_date)
Run Code Online (Sandbox Code Playgroud)
小智 8
一个问题是Ruby Time对象具有纳秒精度,但大多数数据库具有至多微秒的精度.解决这个问题的最好方法是将Time.now(或使用timecop)存储为一个整数.阅读我写的关于此的帖子:http: //blog.solanolabs.com/rails-time-comparisons-devil-details-etc/
| 归档时间: |
|
| 查看次数: |
14453 次 |
| 最近记录: |