Falko
Falko

Reputation: 1035

Rspec matcher for random number in a hash value

I'm trying to fix a test, but because we run the tests randomly, the change_requests end up being random, so the expected hash in the before do block always ends up failing.

Error Example:

    Diff:
       @@ -1,4 +1,4 @@
       -:change_requests => [0, 0],
       +:change_requests => [23, 24],

Test:

    let(:expected_hash) do
      {
        from_admin_user: user.first_name,
        station_id: station.id,
        ten_minutes_before_reminder: false,
        one_hour_after_reminder: false,
        change_requests: [0, 0],
        one: requests[0][:new_price],
        two: 'NO CHANGE',
        three: 'NO CHANGE',
        four: requests[1][:new_price],
        price_change_at_time: nil
      }

    end

    before do
      expect(PriceChangeService).to receive(:new) do |hash|
        expect(hash).to eq expected_hash
        price_change_service
      end
    end

Is there away to solve this by, for example, adding a random number matcher somehow to the change_requests value?

Upvotes: 1

Views: 632

Answers (2)

Anuj Khandelwal
Anuj Khandelwal

Reputation: 1244

Since the value of change_requests is a dynamic one, we basically need to check two things:

1) change_requests is an array which contains two elements

2) The rest of the hash, apart from change_requests is as expected (Here, change_requests is removed from the expected_hash declaration)

We could achieve this by using the reject method on the newly created PriceChangeService object to check all keys and values EXCEPT change_requests. Additionally, we would need to check the change_requests value as mentioned in point (1).

This could be done as follows:

before do
  expect(PriceChangeService).to receive(:new) do |hash|
    expect(hash.reject{|k, v| k == : change_requests}).to eq(expected_hash)
    expect(hash[:change_requests].class).to eq(Array)
    expect(hash[:change_requests].length).to eq(2)
    price_change_service
  end
end

You could additionally check for the type of elements that are being expected as well.

Upvotes: 1

max
max

Reputation: 102134

You could remove the random key with:

expect(hash.except(:change_requests )).to eq 
  expected_hash.except(:change_requests)

Or stub the method which generates change_requests to make it deterministic.

Upvotes: 2

Related Questions