如果哈希数组具有属性/值对,如何编写rspec测试

时间:2019-07-17 17:48:02

标签: ruby rspec

给出一个散列数组,我想检查每个散列是否包含特定的键和值。以下内容无效:

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

我无法从匹配错误中得知为什么它不起作用,但我认为这与对输入参数或环境的had_attributes期望有关。

我通过制作如下的自定义匹配器解决了该问题。这行得通,但如果可能的话,我不想偏离标准的rspec。

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") ) }

4 个答案:

答案 0 :(得分:1)

我可能会做这样的事情:

    mpg cyl  disp  hp drat    wt  qsec vs am gear carb
1  18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
2  14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
3  22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
4  17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
5  16.4   8 275.8 180 3.07 4.070 17.40  0  0    3    3
6  17.3   8 275.8 180 3.07 3.730 17.60  0  0    3    3
7  15.2   8 275.8 180 3.07 3.780 18.00  0  0    3    3
8  10.4   8 472.0 205 2.93 5.250 17.98  0  0    3    4
9  10.4   8 460.0 215 3.00 5.424 17.82  0  0    3    4
10 14.7   8 440.0 230 3.23 5.345 17.42  0  0    3    4
11 15.5   8 318.0 150 2.76 3.520 16.87  0  0    3    2
12 15.2   8 304.0 150 3.15 3.435 17.30  0  0    3    2
13 13.3   8 350.0 245 3.73 3.840 15.41  0  0    3    4

答案 1 :(得分:1)

我认为该断言不起作用,因为 have_attributes 不适用于普通的 ruby​​ 哈希。如果您使用的是 vanilla 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>'

我相信,如果您正在使用的对象具有您正在寻找的任何键值的 attribute 访问器,那么匹配器就会起作用。前任。如果您有一组 OpenStruct,则同时使用 match_arrayhave_attributes 都可以。如果您使用的是 ActiveRecord 或 OpenStruct 等奇特的库,这些通常可以通过元编程自动获得。

否则,您必须自己定义这些属性,或者对哈希键而不是属性进行断言。

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

进行如下自定义匹配器:

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") ) }

可悲的是,我不确定为什么问题中的方法行不通。