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

Testing a clone fails, unless the clone is invoked first #1040

Closed
forforf opened this issue Aug 13, 2013 · 2 comments
Closed

Testing a clone fails, unless the clone is invoked first #1040

forforf opened this issue Aug 13, 2013 · 2 comments

Comments

@forforf
Copy link

forforf commented Aug 13, 2013

When doing a customized deep clone, I ran across a situation where the test will fail unless the variable assigned by let is called first (see the spec code below).

The cloning does work, but the normal test case fails.

Code to reproduce:

File: cloner.rb

class Cloner
  def clone_array_of_hashes(a)
    a.map{|h| h.clone}
  end
end

File: cloner_spec.rb

require_relative "./cloner"

describe Cloner do
  let(:cloner) {Cloner.new}
  let(:orig_ah) { [{a: "A"},{b: "B"}] }
  let(:cloned_ah) { cloner.clone_array_of_hashes(orig_ah) }

  it "passes" do
    cloned_ah[0] #this is the only difference between the two tests
    orig_ah[0][:a] = "AA"
    expect(orig_ah[0]).to_not eq(cloned_ah[0])
  end

  it "fails but should pass" do
    orig_ah[0][:a] = "AA"
    expect(orig_ah[0]).to_not eq(cloned_ah[0])
  end
end

Notes:

  • Invoking cloned_ah instaed of cloned_ah[0] works to pass the test as well.
  • The issue exists whether clone or dup is used

The issue occurs with RSpec 2.14 and 2.12, and Ruby 1.9.3 and 2.0.0

I had a similar issue a while ago with regexes (#820) with the variable needing to be invoked first, but I'm not sure if the similarities extend beyond that.

@soulcutter
Copy link
Member

This isn't a bug - let variables are lazily instantiated, so in your failing test cloned_ah is instantiated after you modify orig_ah. If you need to control the order of instantiation you should probably be explicit about the ordering using a before block.

Alternately you could probably get away with using let! for cloned_ah, which is functionally equivalent to initializing it in a before block.

https://www.relishapp.com/rspec/rspec-core/v/2-14/docs/helper-methods/let-and-let

@forforf
Copy link
Author

forforf commented Aug 13, 2013

Got it, obvious in hindsight. Thanks!

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