In Rspec I am testing a hash that contains an array like this:
subject { described_class.call(build: build_one, user:)
it 'returns the correct data' do
response = subject
expected_response = {
id: build_one.id,
status: {
key: 'active',
name: 'Active'
},
build_type: 'SystemBuild',
calculated_type_id: CalculatedType.standard.id,
build_time: build_one.build_time,
summary: 'Lorem ipsum dolor sit amet...',
data: [
{id: '1', name: '', parent: ''},
{id: '1.1', name: 'Calc type 1', parent: '1'},
{id: '1.2', name: 'Calc type 2', parent: '1'},
{id: '1.3', name: 'Calc type 3', parent: '1'},
{id: '1.1.1', name: 'Value 1', parent: '1.1'},
{id: '1.1.2', name: 'Value 2', parent: '1.1'},
{id: '1.2.1', name: 'Value 3', parent: '1.2'},
{id: '1.3.1', name: 'Value 4', parent: '1.3'},
{id: '1.3.2', name: 'Value 5', parent: '1.3'},
{id: '1.3.3', name: 'Value 6', parent: '1.3'}
]
}
expect(response).to match(expected_response)
end
My problem is that the data
array is not necessarily in the same order as I have written in the expected_response
.
I could of course changed the order in the expected_response
, but I don't want to restrict it in this way. The thing is for the application, the array order does not matter at all, and changing other parts of the application might change the order. The only important thing is that all elements are present in the array.
When I run the test, I get the following:
Diff:
:build_time: 2024-06-22 10:17:55.0000000000 -0700,
:build_type: "SystemType",
:calculated_type_id: 3,
:id => 234,
-:data => [{:id=>"1", :name=>"", :parent=>""}, {:id=>"1.1", :name=>"Calc type 1", :parent=>"1"}, {:id=>"1.2", :name=>"Calc type 2", :parent=>"1"}, {:id=>"1.3", :name=>"Calc type 3", :parent=>"1"}, {:id=>"1.1.1", :name=>"Value 1", :parent=>"1.1"}, {:id=>"1.1.2", :name=>"Value 2", :parent=>"1.1"}, {:id=>"1.2.1", :name=>"Value 3", :parent=>"1.2"}, {:id=>"1.3.1", :name=>"Value 4", :parent=>"1.3"}, {:id=>"1.3.2", :name=>"Value 5", :parent=>"1.3"}, {:id=>"1.3.3", :name=>"Value 6", :parent=>"1.3"}]
+:data => [{:id=>"1", :name=>"", :parent=>""}, {:id=>"1.1", :name=>"Calc type 1", :parent=>"1"}, {:id=>"1.2", :name=>"Calc type 2", :parent=>"1"}, {:id=>"1.3", :name=>"Calc type 3", :parent=>"1"}, {:id=>"1.1.1", :name=>"Value 1", :parent=>"1.1"}, {:id=>"1.2.1", :name=>"Value 3", :parent=>"1.2"}, {:id=>"1.3.2", :name=>"Value 5", :parent=>"1.3"}, {:id=>"1.1.2", :name=>"Value 2", :parent=>"1.1"}, {:id=>"1.3.1", :name=>"Value 4", :parent=>"1.3"}, {:id=>"1.3.3", :name=>"Value 6", :parent=>"1.3"}]
:status => {:key=>"active", :name=>"Active"},
:summary => "Lorem ipsum dolor sit amet..."
I thought that match(...)
would disregard the order of the data
array and just check that all elements exists. Is there a way to do this without having to check each element in the hash?
When using match
with a data structure (array or hash), you can utilize other RSpec matchers within that structure, e.g. contain_exactly
:
let(:expected) do
{
data: contain_exactly(1, 2, 3)
}
end
it 'matches' do
expect({ data: [2, 3, 1] }).to match(expected)
end