我在Post模型上使用此类方法获取档案
def self.archives
Post.unscoped.select("YEAR(created_at) AS year, MONTHNAME(created_at) AS month, COUNT(id) AS total")
.group("year, month, MONTH(created_at)")
.order("year DESC, MONTH(created_at) DESC")
end
这是我为我的方法所写的测试
context '.archives' do
first = FactoryGirl.create(:post, published_at: Time.zone.now)
second = FactoryGirl.create(:post, published_at: 1.month.ago)
it 'returns articles archived' do
archives = Post.archives()
expect(
[{
year: first.published_at.strftime("%Y"),
month: first.published_at.strftime("%B"),
published: 1
},
{
year: second.published_at.strftime("%Y"),
month: second.published_at.strftime("%B"),
published: 1
}]
).to match_array(archives)
end
end
但是我收到以下错误
expected collection contained: [#<Post id: nil>, #<Post id: nil>]
actual collection contained: [{:year=>"2017", :month=>"October", :published=>1}, {:year=>"2017", :month=>"September", :total=>1}]
the missing elements were: [#<Post id: nil>, #<Post id: nil>]
the extra elements were: [{:year=>"2017", :month=>"October", :total=>1}, {:year=>"2017", :month=>"September", :total=>1}]
因此,虽然我创建了2个工厂,但archives
数组为空。我做错了什么?
答案 0 :(得分:1)
实际数组不为空,它是一个包含未设置ID的两个Post实例的数组(因为if(result == null || !result.Any())
{
return null;
}
方法中的Select
不包含id字段)。
您可以将预期的哈希值与.archives
进行比较,但是使用类似的smth:
archives
答案 1 :(得分:1)
Rspec标准是使用let
语法在上下文或描述块中定义变量。测试看起来应该是这样的:
describe '.archives' do
let!(:first) { FactoryGirl.create(:post, published_at: Time.zone.now) }
let!(:second) { FactoryGirl.create(:post, published_at: 1.month.ago) }
it 'returns year, month, and total for articles archived' do
actual_attributes = Post.archives.map { |post| [post.year, post.month, post.total] }
expected_total = 1 # I don't know why the query is returning 1 for total, but including this for completeness
expected_attributes = [first, second].map { |post| [post.created_at.year, post.created_at.strftime("%B"), expected_total] }
expect(actual_attributes).to match_array(expected_attributes)
end
end
这里的问题是您将仅使用少量属性(SQL查询的结果)提取的记录与完全形成的记录(由您的测试创建)进行比较。此测试从两个组中提取适用的属性并进行比较。