How to test with Rspec that a key exists inside a hash that contains an array of hashes

34,855

Solution 1

RSpec allows you to use the have_key predicate matcher to validate the presence of a key via has_key?, like so:

subject { described_class.order_items_by_revenue }

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

Solution 2

If you explicitly want to test only the first hash in your array mapped to :data, here are your expects given what you wrote above:

data = subject[:data].first
expect(data).not_to be_nil
expect(data.has_key?(:revenue)).to be_truthy
expect(data[:revenue]).to eq 600

Alternatively, for the second expectation, you could use expect(data).to have_key(:revenue) as Chris Heald pointed out in his answer which has a much nicer failure message as seen in the comments.

  1. The first "expectation" test if the subject has the first hash. (You could alternately test if the array is empty?)
  2. The next expectation is testing if the first hash has the key :revenue
  3. The last expectation tests if the first hash :revenue value is equal to 600

You should read up on RSpec, it's a very powerful and usefull testing framework.

Solution 3

This issue can be solved via testing of each hash by key existing with appropriate type of value. For example:

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

Solution 4

this works for me in 'rspec-rails', '~> 3.6'

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

expect(array_of_hashes).to include(have_key(:id))
Share:
34,855
Mark Datoni
Author by

Mark Datoni

Updated on January 06, 2020

Comments

  • Mark Datoni
    Mark Datoni over 4 years

    I have a Model method that returns the following when executed.

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

    I would like to test to make sure that "revenue" in the first hash is there and then test that the value is equal to 600.

    subject { described_class.order_items_by_revenue }
    
    it "includes revenue key" do
      expect(subject).to include(:revenue)
    end
    

    I am completely lost on how to test this with Rspec.