【问题标题】:Rspec match array of hashesRspec匹配哈希数组
【发布时间】:2014-07-12 00:42:02
【问题描述】:

我有一个哈希数组,为了论证,它看起来像这样:

[{"foo"=>"1", "bar"=>"1"}, {"foo"=>"2", "bar"=>"2"}]

使用 Rspec,我想测试 "foo" => "2" 是否存在于数组中,但我不在乎它是第一项还是第二项。我试过了:

[{"foo" => "1", "bar" => "2"}, {"foo" => "2", "bar" => "2"}].should include("foo" => "2"))

但这不起作用,因为哈希值应该完全匹配。有没有办法部分测试每个哈希的内容?

【问题讨论】:

  • [{"foo" => "1", "bar" => "2"}, {"foo" => "2", "bar" => "2"}].flat_map(&:to_a).should include(["foo","2"]) 也可以。

标签: ruby arrays hash rspec


【解决方案1】:

使用Composable Matchers

hashes = [{"foo" => "1", "bar" => "2"}, {"foo" => "2", "bar" => "2"}]
expect(hashes)
  .to match([
    a_hash_including('foo' => '2'), 
    a_hash_including('foo' => '1')
  ])

【讨论】:

    【解决方案2】:

    您可以使用可组合的匹配器

    http://rspec.info/blog/2014/01/new-in-rspec-3-composable-matchers/

    但我更喜欢像这样定义一个自定义匹配器

    require 'rspec/expectations'
    
    RSpec::Matchers.define :include_hash_matching do |expected|
      match do |array_of_hashes|
        array_of_hashes.any? { |element| element.slice(*expected.keys) == expected }
      end
    end
    

    并在这样的规范中使用它

    describe RSpec::Matchers do
      describe '#include_hash_matching' do
        subject(:array_of_hashes) do
          [
            {
              'foo' => '1',
              'bar' => '2'
            }, {
              'foo' => '2',
              'bar' => '2'
            }
          ]
        end
    
        it { is_expected.to include_hash_matching('foo' => '1') }
    
        it { is_expected.to include_hash_matching('foo' => '2') }
    
        it { is_expected.to include_hash_matching('bar' => '2') }
    
        it { is_expected.not_to include_hash_matching('bar' => '1') }
    
        it { is_expected.to include_hash_matching('foo' => '1', 'bar' => '2') }
    
        it { is_expected.not_to include_hash_matching('foo' => '1', 'bar' => '1') }
    
        it 'ignores the order of the keys' do
          is_expected.to include_hash_matching('bar' => '2', 'foo' => '1')
        end
      end
    end
    
    
    Finished in 0.05894 seconds
    7 examples, 0 failures
    

    【讨论】:

    • 如果你想让它与使用符号的哈希一起工作,你可以这样做: RSpec::Matchers.define :include_hash_matching do |expected|匹配 |array_of_hashes| array_of_hashes.any?做 |元素|预期 = 预期的.stringify_keys 元素 = element.stringify_keys element.slice(*expected.keys) == 预期的结束结束结束
    【解决方案3】:

    怎么样?

    hashes = [{"foo" => "1", "bar" => "2"}, {"foo" => "2", "bar" => "2"}]
    expect(hashes).to include(include('foo' => '2'))
    

    【讨论】:

    【解决方案4】:

    您可以使用any? 方法。有关文档,请参阅 this

    hashes = [{"foo" => "1", "bar" => "2"}, {"foo" => "2", "bar" => "2"}]
    expect(hashes.any? { |hash| hash['foo'] == '2' }).to be_true
    

    【讨论】:

    • 非常感谢,你拯救了我的一天
    【解决方案5】:

    如果单独测试哈希不是严格要求,我会这样做:

    [{"foo" => "1", "bar" => "2"}, {"foo" => "2", "bar" => "2"}].map{ |d| d["foo"] }.should include("2")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-14
      • 1970-01-01
      • 2014-08-26
      • 2021-11-18
      • 1970-01-01
      • 2021-04-23
      • 2019-10-10
      相关资源
      最近更新 更多