Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested hash_including not working properly along with RSpec #900

Open
jefgarzon opened this issue Sep 8, 2020 · 2 comments
Open

Nested hash_including not working properly along with RSpec #900

jefgarzon opened this issue Sep 8, 2020 · 2 comments

Comments

@jefgarzon
Copy link

jefgarzon commented Sep 8, 2020

When using hash_including expectations don't pass at least I tell it explicitly to use Webmock::API.hash_including.

Those two version should pass but first one don't.

fails.rb

require 'rspec'
require 'webmock/rspec'
require 'rest-client'

RSpec.describe 'hash_including' do

  it 'must passed' do

    url = 'http://test.com/resource'

    stub_request(:post, url)

    RestClient.post(url,
      {
        a: 1,
        b: {
          c: 3,
          d: 4
        }
      }.to_json,
      {
        content_type: :json
      }
    )

    expect(a_request(:post, url)
      .with(body: hash_including(
        a: 1,
        b: hash_including(c: 3)
      ))).to have_been_made
  end
end

pass.rb

require 'rspec'
require 'webmock/rspec'
require 'rest-client'

RSpec.describe 'hash_including error' do

  it 'must passed' do

    url = 'http://test.com/resource'

    stub_request(:post, url)

    RestClient.post(url,
      {
        a: 1,
        b: {
          c: 3,
          d: 4
        }
      }.to_json,
      {
        content_type: :json
      }
    )

    expect(a_request(:post, url)
      .with(body: hash_including(
        a: 1,
        b: WebMock::API.hash_including(c: 3)
      ))).to have_been_made
  end
end

Not sure if we must specify the hash_including version to use each time, but researching a little bit it looks like WebMock version is stringifying the keys of the expected partial hash but Rspec version don't, so the error occurs once the key-to-key comparison is being made and do to different type of the keys, the response body returns nil for all keys since it's being query with symbol instead of string.

webmock

class HashArgumentMatcher
def initialize(expected)
@expected = Hash[WebMock::Util::HashKeysStringifier.stringify_keys!(expected, deep: true).sort]
end

rspec
https://github.com/rspec/rspec-mocks/blob/0a52e0a86b126b4bab94d277b2ad99a7492dc37d/lib/rspec/mocks/argument_matchers.rb#L178-L181

@bblimke
Copy link
Owner

bblimke commented Sep 11, 2020

@jefgarzon it's only when using nested hash_including right? I don't think nested hash_including has every been tested in WebMock

@bblimke
Copy link
Owner

bblimke commented Sep 11, 2020

WebMock's version of hash_including has ben developed to cover hash_including in other environments than Rspec. When RSpec is used, default RSpec's hash_including is supposed to be used.
I guess the expected result is to have the first example pass.
Perhaps the keys should be stringified as well, before passing the hash to RSpec matcher, though these would have to be stringified in the nested hash_including's as well, which is tricky.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants