3 mistakes to avoid in your rspec tests
I'm a web-focused developer with a passion for exploring new ideas and hopefully sharing more of them through this blog 😃
Search for a command to run...
I'm a web-focused developer with a passion for exploring new ideas and hopefully sharing more of them through this blog 😃
No comments yet. Be the first to comment.
When to use for, map, doseq, and run!

Property based testing leading to unexpected URL discoveries

Some Takeaways from AI-assisted Rescript Exploration

Do you believe your job can be done by AI? Up until very recently I believed this was all hype. No way this could happen. There have always been proclamations of new technologies like AI taking jobs. Most of the time dismissed as fantasy, most takes ...

Return the most frequently used terminal commands

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
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
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 }
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_forandshared_contextare 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