Rspec - 存档数组以匹配测试数组
Rspec - archives array to match tested array
我在我的 Post 模型上使用这个 class 方法来获取档案
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
数组是空的。我做错了什么?
实际数组不为空,它是两个未设置 id 的 Post 实例的数组(因为 .archives
方法中的 Select
不包含 id 字段)。
您可以不将预期的哈希值与 archives
进行比较,而是将其与类似的东西进行比较:
actual = Post.archives().map do |post|
{ year: post["year"].to_s, month: post["month"], published: post["total"] }
end
expected = [{
year: first.published_at.strftime("%Y").to_s,
month: first.published_at.strftime("%B"),
published: 1
},
{
year: second.published_at.strftime("%Y").to_s,
month: second.published_at.strftime("%B"),
published: 1
}]
expect(actual).to match_array(expected)
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 查询的结果)与完整格式的记录(由您的测试创建)。此测试从两组中提取适用的属性并进行比较。
我在我的 Post 模型上使用这个 class 方法来获取档案
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
数组是空的。我做错了什么?
实际数组不为空,它是两个未设置 id 的 Post 实例的数组(因为 .archives
方法中的 Select
不包含 id 字段)。
您可以不将预期的哈希值与 archives
进行比较,而是将其与类似的东西进行比较:
actual = Post.archives().map do |post|
{ year: post["year"].to_s, month: post["month"], published: post["total"] }
end
expected = [{
year: first.published_at.strftime("%Y").to_s,
month: first.published_at.strftime("%B"),
published: 1
},
{
year: second.published_at.strftime("%Y").to_s,
month: second.published_at.strftime("%B"),
published: 1
}]
expect(actual).to match_array(expected)
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 查询的结果)与完整格式的记录(由您的测试创建)。此测试从两组中提取适用的属性并进行比较。