如何使用Rspec测试包含哈希数组的哈希中是否存在一个键

44

我有一个Model方法,当执行时返回以下内容。

 {"data" => [
 {"product" => "PRODUCTA", "orders" => 3, "ordered" => 6, "revenue" => 600.0},
 {"product" => "PRODUCTB", "orders" => 1, "ordered" => 5, "revenue" => 100.0}]}

我想测试第一个哈希表中的“revenue”是否存在,然后测试其值是否等于600。

subject { described_class.order_items_by_revenue }

it "includes revenue key" do
  expect(subject).to include(:revenue)
end

我完全不知道如何使用Rspec进行测试。

4个回答

57

使用RSpec,您可以使用have_key 预测匹配器通过has_key?来验证关键字是否存在,如下所示:

subject { described_class.order_items_by_revenue }

it "includes revenue key" do
  expect(subject.first).to have_key(:revenue)
end

当我尝试这个例子时,我得到了以下内容-------- Failure/Error: expect(subject.first).to have_key(:revenue) 预期 ["data", [{"product"=>"PRODUCTA", "orders"=>3, "ordered"=>13596, "revenue"=>600.0}, {"product"=>"PRODUCTB", "orders"=>1, "ordered"=>2568, "revenue"=>100.0}]] 响应 `has_key?`。 - Mark Datoni
你想让主题变成 subject { described_class.order_items_by_revenue["data"] },还是你想测试 subject["data"].first。抱歉。 - Chris Heald

8

可以通过测试每个哈希键是否存在适当类型的值来解决此问题。例如:

describe 'GetCatsService' do
  subject { [{ name: 'Felix', age: 25 }, { name: 'Garfield', age: 40 }] }

  it { is_expected.to include(include(name: a_kind_of(String), age: a_kind_of(Integer)))}
end

# GetCatsService
#  should include (include {:name => (a kind of String), :age => (a kind of Integer)})

这不是完全正确的,应该是:it { is_expected.to all match(name: a_kind_of(String), age: a_kind_of(Integer)) }。在你的例子中,如果你将“Felix”改为数字1,它仍然会通过。 - fatfrog

7
如果您明确希望测试数组中映射到:data第一个哈希,那么根据您上面所写的内容,以下是您的expect结果:
data = subject[:data].first
expect(data).not_to be_nil
expect(data.has_key?(:revenue)).to be_truthy
expect(data[:revenue]).to eq 600

作为第二个期望的替代方案,你可以使用expect(data).to have_key(:revenue),正如Chris Heald在他的答案中指出的那样,它具有更好的失败消息,如评论中所示。
  1. 第一个“期望”测试主题是否具有第一个哈希。(您还可以选择测试数组是否为空empty?
  2. 接下来的期望是测试第一个哈希是否具有键:revenue
  3. 最后一个期望测试第一个哈希:revenue值是否等于600

你应该了解RSpec, 它是一个非常强大和有用的测试框架。


所以我感觉好一点了,因为我实际上尝试过其中的几个。当我尝试你列表中的第二个时,我会收到以下错误。 Failure/Error: expect(subject.first.has_key?(:revenue)).to be_truthy NoMethodError: undefined method `has_key?' for # - Mark Datoni
看起来应该是 subject[:data].first - wspurgin

2

这对我来说是有效的,在'rspec-rails','〜> 3.6'中。

array_of_hashes = [
  {
    id: "1356786826",
    contact_name: 'John Doe'
  }
]

expect(array_of_hashes).to include(have_key(:id))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接