1

I have been told that it makes sense to use let!() instead of before(:each) block. However, I can't see much logic in doing that. Does it actually make any sense to make something like in the example below:

context 'my super context' do
  let!(:something) do
    Model.create(subject: "Hello", body: "World")
  end

  it '...' do
    # We never call something
    # All we want is just to evaluate and create the record
  end
end

Keep in mind that you won't call something anywhere in the example at all. Technically I don't see much difference between that and this, unless it's actually more strict and easy to understand without documentation just like plain English:

context 'my super context' do
  before(:each) do
    Model.create(subject: "Hello", body: "World")
  end

  it '...' do
    # We never call something
    # All we want is just evaluate and create the record
  end
end

Could someone help me to understand the idea behind the rule I was given? I can understand why you would use let instead of before(:all) and before(:each) with the variable inside. But here it just feels like they just blindly follow the phrase "use a let helper instead of a before block" found somewhere in the blog post.

Thank you very much!

Dave Schweisguth
  • 36,475
  • 10
  • 98
  • 121
rudkovskyi
  • 97
  • 5
  • As far as i am concerned let is lazy evaluated. A before will create all the records even if not referenced. The variables defined with let will be only evaluated if the were used later in your tests – theDrifter Aug 29 '16 at 21:11
  • 1
    The first answer here goes into some more detail http://stackoverflow.com/questions/5359558/when-to-use-rspec-let – theDrifter Aug 29 '16 at 21:12
  • 1
    @theDrifter "close as duplicate" :) – Ven Aug 29 '16 at 21:14
  • 1
    @Ven not really it is completely different question. **I am talking about `let!`** I know the difference between let, and why would you use it instead of before. There's the point. I don't understand the point to define `let!(:abcd) { Model.create() }` evaluate the code. It is gonna create the record, but never actually to call `abcd` later. I mean you could do that inside the block with the same luck. There's no difference at all, except the second example is clearer and more logical. – rudkovskyi Aug 29 '16 at 21:16

1 Answers1

3

No, it is not a best practice to always use let! rather than a before block. You're correct:

  • If you want to run a block of code before every example, and you need that code to return a value, use let!.
  • If you want to run a block of code before every example, but you don't need to pass a value from that code directly to your example, use before. (Using let! would mislead the reader into thinking that its value was being used.)

Note that both let! and before blocks should be used sparingly in any case. They create the risk of later test writers adding tests in the same block that don't need the result of the let! or before, making those tests harder to understand and slower.

Dave Schweisguth
  • 36,475
  • 10
  • 98
  • 121