如果哈希数组具有 attribute/value 对,我该如何编写 rspec 测试

How do I write an rspec test if an array of hashes has a attribute/value pair

给定一个哈希数组,我想检查每个哈希是否包含特定的键和值。以下无效:

      it { expect(some_array).to all( have_attributes(:some_key => 'some_value') ) }

我无法从匹配错误中看出它为什么不起作用,但我认为这与预期有关 have_attributes 与输入参数或环境有关。

我会遍历 subject.body 并在循环中写下期望 例如

subject.body.each do |entry|
   it { expect(entry[:some_key]).to eq "some_value"}
end

我可能会这样做:

it do 
  expect(subject.body.map { |elem| elem[:some_key] }).to all( eq "some_value" ) }
end

按如下方式制作自定义匹配器:

RSpec::Matchers.define :have_member_with_value do |expected_key, expected_value|
  match do |actual|
    actual[expected_key] == expected_value
  end
end

用法:

it { expect(some_array).to all( have_member_with_value(:some_key, "some_value") ) }

遗憾的是,我不确定为什么问题中的方法不起作用。

我认为断言不起作用,因为 have_attributes 不适用于纯 ruby 散列 keys。如果您使用的是香草 Ruby 哈希,则无法像访问属性一样访问哈希键。

考虑:

a = OpenStruct.new(hello: 'you')
b = { hello: 'you' }

a.hello # this is an attribute automatically defined via OpenStruct
=> "you"

b.hello # this is a regular ol' key
NoMethodError: undefined method `hello' for {:hello=>"you"}:Hash
from (pry):79:in `<main>'

我相信如果您正在使用的对象具有您正在寻找的任何键值的 属性 访问器,那么匹配器将会工作。前任。如果您有一个 OpenStructs 数组,则可以同时使用 match_arrayhave_attributes。如果您使用像 ActiveRecord 或 OpenStruct 这样的高级库,这些通常可以通过元编程自动获得。

否则,您必须自己定义这些属性,或者在散列键而不是属性上断言。