Ah, I didn't even think that RSpec would be reusing the original object when it checked the expectation. That makes sense though, thanks for the quick response!!
On Wednesday, May 11, 2016 at 6:29:40 PM UTC-7, Jon Rowe wrote: > > 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] <javascript:> > 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] <javascript:>. > To post to this group, send email to [email protected] <javascript:>. > 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/5fd9c2a1-5e6d-48e3-a799-29751a3037ef%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
