Posted over 5 years ago. Visible to the public.

Using RSpec's late resolving of "let" variables for cleaner specs

Consider the following:

Copy
describe '#something' do context 'with lots of required arguments' do it 'should work' do subject.something(:foo => 'foo', :bar => 'bar', :baz => 'baz').should == 'Hello world' end it 'should work again' do subject.stub :target => 'universe' subject.something(:foo => 'foo', :bar => 'bar', :baz => 'baz').should == 'Hello universe' end it 'should work yet again' do subject.stub :target => 'multiverse' subject.something(:foo => 'foo', :bar => 'bar', :baz => 'baz').should == 'Hello multiverse' end end end

Something like that gets ugly and/or annoying once you require more than just a simple method call, e.g. with many arguments that are required for a method for some reason.

This cleans up your spec, making it easier to see the requirements at a first glance:

Copy
describe '#something' do context 'with lots of required arguments' do let(:result) { subject.something(:foo => 'foo', :bar => 'bar', :baz => 'baz') } it 'should work' do result.should == 'Hello world' end it 'should work again' do subject.stub :target => 'universe' result.should == 'Hello universe' end it 'should work yet again' do subject.stub :target => 'multiverse' result.should == 'Hello multiverse' end end end

The reason why this works is because RSpec will evaluate the block assigned for the let call only when result is actually called. This way you can manipulate objects or other data before using the short-hand reference to your method call.

Yes, it is quite similar to using variables introduced via let in before blocks.

By refactoring problematic code and creating automated tests, makandra can vastly improve the maintainability of your Rails application.

Author of this card:

Avatar
Arne Hartherz
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Arne Hartherz to makandropedia