Skip to content

let(:me) {get(that).for(you)}

2012/01/09

Before blocks in rspec are good for factoring out certain types of common setup (stubs, in particular.) However, they are not the ideal solution for every test setup need. For example, they’re commonly abused to create one or more instance variables that are used as test data, or assertions are made against them, etc.

Typical shared setup block in rspec

Rspec provides another (and sadly perhaps lesser known) facility for accomplishing the same end in a more efficient fashion. The lazily evaluated let(:symbol) {block} provides a way to extract objects (especially the current system under test), especially those which are used in multiple examples within one or more describe blocks, but perhaps not every example within a given describe or context.

The reason this is more efficient than an instance variable in a before block is that before blocks are executed on each test run, so those data values instantiated regardless, times n examples. That’s assignment cost, memory cost, and parsing cost.

Lazily evaluated blocks only incur cost when they are used. That is to say the parse cost is incurred regardless, but assignment and memory cost are only incurred in the examples which use the values returned by the instance methods that let() creates. It is easy to factor example 1 to use let blocks instead of a before block (and looks cleaner, in my opinion.)

Shared setup, using let()

Another benefit is that lazy evaluation provides a facility to pass different data in from each spec, since the block is evaluated when the method is called, which can be after some individual setup occurs.

Let blocks allow for flexible common setup definition

As you can see, let() can be a very powerful and useful construct, if properly employed. I first discovered let() in a slide deck entitled Pure RSpec. Check it out for this and other fun RSpec goodness, and as always, happy hacking!

Advertisements

From → Programming

Leave a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: