Rspec - 存档数组以匹配测试的数组

时间:2017-10-04 21:12:05

标签: ruby-on-rails ruby unit-testing rspec rspec-rails

我在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数组为空。我做错了什么?

2 个答案:

答案 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查询的结果)提取的记录与完全形成的记录(由您的测试创建)进行比较。此测试从两个组中提取适用的属性并进行比较。