rspec before let

16
RSpec before/let for creating objects

Upload: rkingucla

Post on 15-Jul-2015

136 views

Category:

Technology


0 download

TRANSCRIPT

RSpecbefore/let for creating objects

Rspec mysteries

• Switch ordering of specs, and they go from passing to failing

• before(:each) is better than before(:all), but why?

• before(:all) creates db records once, seems like we should use it because it is faster

• Why let, rather than let! or instance variable in before block?

Before(:all)

• runs before each describe/context block

• persists in database

Before(:each)

• runs before each example (it-block)

• cleans itself up after each example

• slower than before(:all) if you have a lot of FactoryGirl inserts

Let

• lazy loads the object

• cached across multiple calls in the same example but not across examples

• cleans itself up after it-block

Let!

• runs right away at the beginning of each it-block

• cached across multiple calls in the same example but not across examples

• cleans itself up after it-block

Code sample

Benchmarks

before(:all)before(:all) before(:each)before(:each)

10 it-blocks10 it-blocks 0.076585 seconds 0.394481 seconds

30 it-blocks30 it-blocks 0.289422 seconds 1.090072 seconds

Struct.new Struct.new instead of instead of

FactoryGirlFactoryGirl0.207315 seconds 0.202621 seconds

Tips

• Most of the time you should be using let and/or before(:each)

• let is almost always preferable to reference objects

• instance variables spring into existence only when necessary

• before(:each) will create all objects even if the example doesn’t use it

Tips

• before(:all) shouldn’t really be used for variable setup, because it introduces an order dependency between specs

• Good use cases: opening a network connection, pre-seeding caches

• If you use before(:all), think about using corresponding after(:all) for clean-up

Tips

• before(:each) can be used to instantiate objects to make specs easier to read, if there is a lot of setup involved before an example

• If you need records in the db without first referencing an object, before(:each) seems to be a better choice than let-bang

Tips

• Don’t mix before and let together, i.e. before(:each); let(:foo) {}; end

• Warning in RSpec 2:• `let` declarations are not intended to be called in a `before(:all)` hook, as they exist

to define state that is reset between each example, while `before(:all)` exists to define state that is shared across examples in an example group.