ruby-on-rails – Rails – 测试使用DateTime.now的方法
我有一个使用DateTime.now对某些数据执行搜索的方法,我想测试各种日期的方法,但是我不知道如何存储DateTime.now,也不能让它与Timecop一起工作(如果它甚至这样做).
有时间警察我试过 it 'has the correct amount if falls in the previous month' do t = "25 May".to_datetime Timecop.travel(t) puts DateTime.now expect(@employee.monthly_sales).to eq 150 end 当我运行规范我可以看到放置DateTime.now给2015-05-25T01:00:00 01:00但有相同的放置DateTime.now在我测试输出的方法2015-07-24T08:57: 53 01:00(今天). ——————更新——————————- ——————– 我正在将一个before(所有)块中的记录(@employee等)设置成似乎已经导致了这个问题.它只有在Timecop做阻止之后完成设置时才有效.为什么会这样? 解决方法
TL; DR:问题是在Timecop.freeze在规范中调用之后,在Employee中调用了DateTime.now.
Timecop模拟Time,Date和DateTime的构造函数.在冻结和返回之间创建的任何实例(或冻结块内)都将被嘲笑. 从README(我的重点):
所以在创建要嘲笑的Time对象之前调用Timecop.freeze是至关重要的.如果您在阻止之前冻结了RSpec,则会在对象进行评估之前运行.但是,如果您有一个在您设置主题的前一个块(在您的案例中为@employee),并且在嵌套描述中还有另一个块,那么您的主题已经设置,在冻结时间之前调用了DateTime.new. 如果将以下内容添加到员工中,会发生什么 class Employee def now DateTime.now end end 然后运行以下规范: describe '#now' do let(:employee) { @employee } it 'has the correct amount if falls in the previous month',focus: true do t = "25 May".to_datetime Timecop.freeze(t) do expect(DateTime.now).to eq t expect(employee.now).to eq t expect(employee.now.class).to be DateTime expect(employee.now.class.object_id).to be DateTime.object_id end end end 而不是使用冻结块,您还可以在钩子之前和之后冻结并返回rspec: describe Employee do let(:frozen_time) { "25 May".to_datetime } before { Timecop.freeze(frozen_time) } after { Timecop.return } subject { FactoryGirl.create :employee } it 'has the correct amount if falls in the previous month' do # spec here end end 偏离主题,可能看看http://betterspecs.org/ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |