我有以下规格:
require 'spec_helper'
describe Page do
it "has a valid factory" do
create(:page).should be_valid
end
it "is invalid without a title" do
build(:page, title: nil).should_not be_valid
end
it "finds record" do
page = create(:page, title: 'heyo')
Page.unscoped.where(:title => 'heyo').should == page
end
it "finds record with same attributes" do
page = create(:page, title: 'heyo')
Page.unscoped.where(:title => 'heyo').first.attributes.each do |name, val|
expect(page[name]).to eq(val)
end
end
end
我有以下工厂:
model_statuses = ['published', 'draft']
FactoryGirl.define do
factory :page do
title { Faker::Lorem.word + ' Page' }
slug { title ? title.parameterize : nil }
intro { Faker::Lorem.sentence 10 }
content { Faker::Lorem.sentences(5).join ' ' }
status { model_statuses.sample }
end
end
测试失败:
Failures:
1) Page finds record with same attributes
Failure/Error: expect(page[name]).to eq(val)
expected: Fri, 24 Jan 2014 23:33:47 MSK +04:00
got: Fri, 24 Jan 2014 23:33:47 MSK +04:00
(compared using ==)
Diff:
# ./spec/models/page_spec.rb:20:in `block (3 levels) in <top (required)>'
# ./spec/models/page_spec.rb:19:in `each'
# ./spec/models/page_spec.rb:19:in `block (2 levels) in <top (required)>'
2) Page finds record
Failure/Error: Page.unscoped.where(:title => 'heyo').should == page
expected: #<Page id: 1, slug: "heyo", title: "heyo", intro: "Sed sint et nesciunt earum libero eveniet est cupid...", content: "A sunt ab exercitationem quas ex incidunt numquam. ...", created_at: "2014-01-24 19:33:47", updated_at: "2014-01-24 19:33:47", status: "draft">
got: [#<Page id: 1, slug: "heyo", title: "heyo", intro: "Sed sint et nesciunt earum libero eveniet est cupid...", content: "A sunt ab exercitationem quas ex incidunt numquam. ...", created_at: "2014-01-24 19:33:47", updated_at: "2014-01-24 19:33:47", status: "draft">] (using ==)
为什么这些对象及其属性不一样,如何正确检查对象是否相等?
答案 0 :(得分:2)
我看到了测试中不同对象的比较问题。
以下测试:
it "finds record" do
page = create(:page, title: 'heyo')
Page.unscoped.where(:title => 'heyo').should == page
end
当您进行此测试时,您已经从page
测试中获得了一个"has a valid factory"
对象。因此,在执行此测试后,您将拥有两个页面对象,首先是标题nil
,第二个是标题heyo
。现在,当您尝试与下一行中的should
匹配时,Page.unscoped.where(:title => 'heyo')
会返回预期结果,即标题为“heyo”的Page
个数组。你得到一个数组,你正在将数组与一个对象进行比较,这样就会失败。
然后你的第二个测试"finds record with same attributes"
失败的原因是因为你期望第一个Page
对象等于最后Page
个对象,所以这也将失败。
所以修复将在以下两个测试中进行:
it "finds record" do
page = create(:page, title: 'heyo')
Page.unscoped.where(:title => 'heyo').last.should == page
end
it "finds record with same attributes" do
page = create(:page, title: 'heyo')
Page.unscoped.where(:title => 'heyo').last.attributes.each do |name, val|
expect(page[name]).to eq(val)
end
end
请注意在两个测试中使用last
。
database_cleaner
gem是您可能感兴趣的东西。它允许您在每次测试之前清理数据库。建议看一下。
答案 1 :(得分:1)
两个错误的来源都是一样的。
您正在比较其中一个日期,created_at,updated_at,它们似乎没有相同的值。
请注意,日期只会在以字符串形式打印时转到第二个日期 - 它们可能会在不同的级别上有所不同。
从比较中排除日期,或者在失败的站点的代码中进行加注/检查,以查看两个项目之间的小数秒数是否不同。
您可以使用的另一个技巧是在规范范围内删除Time.now/Time.new,以便始终获得一致的结果。
通常情况下,你会在一个之前存根/滥用Time.now:你的规范上下文中的每个块。你想让范围尽可能地缩小,因为如果你不小心这样做,覆盖那个方法可能会产生各种奇怪的副作用。
答案 2 :(得分:0)
您必须冻结案件中的时间,例如使用timecop