Hi Sean This isn’t a bug in RSpec, it’s a “feature” of how Ruby works, the first example fails because the hash is the same when it’s checked by the expectation, you’re mutating the hash before it's checked and the same reference is used in both expectations.
Whilst this may be unintuitive to you it’s not something we can handle, this is the same behaviour as you’d find elsewhere in your code, for example in rails, if you pass a params hash into another object, mutate it outside that object, the value inside that object will also change. Cheers Jon Jon Rowe --------------------------- [email protected] jonrowe.co.uk On Thursday, 12 May 2016 at 11:11, Sean Monroe wrote: > I'm not sure how to write a subject for this, so sorry if it's confusing. > It's best to just show an example. I'm having the following problem with > RSpec 3.4.0 and Ruby 1.9.3. > > Given this RSpec config: > > > RSpec.configure do |config| > config.mock_with :rspec > config.run_all_when_everything_filtered = true > config.filter_run :focus > end > > > And these tests: > > it 'test1' do > test_obj = double > test_hash = { a: 3 } > expect(test_obj).to > receive(:get).with(a_hash_including(test_hash)).and_return(5) > > > test_hash[:a] = 4 > expect(test_obj).to > receive(:get).with(a_hash_including(test_hash)).and_return(6) > > > expect(test_obj.get({ a: 3 })).to eq(5) > expect(test_obj.get({ a: 4 })).to eq(6) > end > > > it 'test2' do > test_obj = double > test_hash = { a: 3 } > expect(test_obj).to > receive(:get).with(a_hash_including(test_hash)).and_return(5) > > > test_hash_dup = test_hash.dup > test_hash_dup[:a] = 4 > expect(test_obj).to > receive(:get).with(a_hash_including(test_hash_dup)).and_return(6) > > > expect(test_obj.get({ a: 3 })).to eq(5) > expect(test_obj.get({ a: 4 })).to eq(6) > end > > test1 fails with: > > > Failure/Error: expect(test_obj.get({ a: 3 })).to eq(5) > > #<Double (anonymous)> received :get with unexpected arguments > expected: (a hash including {:a => 4}) > got: ({:a=>3}) > Diff: > @@ -1,2 +1,2 @@ > -["a hash including {:a => 4}"] > +[{:a=>3}] > > test2 succeeds. > > test2 is almost identical to test1, with the only difference being that I > make a copy of the hash I'm setting a constraint with before mutating it and > passing it to the matcher and constraint. > > This was very unintuitive to me, and took a while to figure out (I got lucky > honestly). > > Is this a bug? If not, is there a part of the documentation that explains > this? > > Thanks! > > -- > You received this message because you are subscribed to the Google Groups > "rspec" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to [email protected] > (mailto:[email protected]). > To post to this group, send email to [email protected] > (mailto:[email protected]). > To view this discussion on the web visit > https://groups.google.com/d/msgid/rspec/8f87469c-d1ea-4735-9146-d4b1bd8a02f2%40googlegroups.com > > (https://groups.google.com/d/msgid/rspec/8f87469c-d1ea-4735-9146-d4b1bd8a02f2%40googlegroups.com?utm_medium=email&utm_source=footer). > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "rspec" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/rspec/6B3BAB03DC1D4A5F818B3FDBDE15B02C%40jonrowe.co.uk. For more options, visit https://groups.google.com/d/optout.
