3 mistakes to avoid in your rspec tests
rspec
is an amazing testing tool for Ruby and Rails apps. I have used it in most of the projects I’ve worked on for a long time. Despite this, I am still prone to make mistakes, so I’ll keep a log of some of them here for future reference
Failing to use hooks correctly
Can you spot the error in the following code?
context 'some setup code here' do
call_some_setup_function(x, y)
it 'validates some conditions' do
expect(sum(1, 2)).to eq 3
end
end
To help you along, this is the error message produced. Any luck?
NoMethodError:
undefined method `call_some_setup_function' for #<Class:0x000040229933d0>
I don’t know about you but it took me quite some time to catch the source of the error. The mistake here is that the setup function should be called in a before
block
context 'some setup code here' do
before { call_some_setup_function(x, y) }
it 'validates some conditions' do
expect(sum(1, 2)).to eq 3
end
end
Not using the full range of matchers
I wouldn’t be able to list all the possible matchers available by default in rspec
here. For that, take a look at the Built-in matchers documentation
Here are some of them that I’ve found to be useful:
expect(result).to be_success # passes if result.success?
expect(result).to be_failure # passes if result.failure?
expect(result).to be_processing # passes if result.processing?
# arrays
expect(actual).to include(expected)
expect(array).to match_array(expected_array) # exact array match
# strings
expect('gato').not_to include('ef')
expect('hola').to include('h')
# changes to object count in DB from some external function
# e.g. HTTP Request
expect { good_post_request }.to change { Account.count }.by(1)
expect { bad_post_request }.not_to change { Account.count }
Repeating specs
If you have a set of specs that you seem to keep repeating in many different tests, put them in a shared_examples
block
shared_examples 'account creation' do
it 'succeeds' do
expect { post :create, data: data }.to change { Account.count }
expect(response).to be_success
# ... and any other expectations for the new account
end
end
# ...and to use it in other places without repeating the examples
include_examples 'account creation'
You can also share and re-use common test setup steps with shared_context
and include_context
Pro tip: Under the hood
shared_examples
,shared_examples_for
andshared_context
are all the same thing
I still need to understand this better and you can find more information in the shared examples documentation
Happy testing!
Cover Photo by Sarah Pflug from Burst