Writing test code is good form and is obviously always recommended. Writing GOOD test is an excellent way to fool-proof the code you (I) have so far, but like everything else, it takes practice!
In an attempt to keep it fresh in my mind, here are a few things I found out recently about writing rspec code...
-
travel_to
is useful... But only allowed once.
Okay. That was a bit dramatic. You can actually use travel_to
in separate blocks as much as you want.
context "first context" do travel_to("2024-12-25") do expect(presents) end end context "second context" do travel_to("2024-12-31") do expect(fireworks) end end
However, you're (I am) not allowed to do some magical shenanigans such as this
context "first context" do travel_to("2024-12-25") do expect(presents) travel_to("2024-12-31") do expect(fireworks) end end end
Not only does it look weird and messy, but also you'll get a big angry error. So yeah.
However in some cases it will be inevitable for the whole file to be enclosed in a travel_to
for some reason or other. And that's when it's a good idea to use travel_back
!
context "first context" do travel_to("2024-12-25") do expect(presents) context "second context" do before do travel_back end travel_to("2024-12-31") do expect(fireworks) end end end end
Simple? Yes. But does it do a good job? Also yes.
Update: I have learned an even better method today. The trick is simply to not make subsequent travel_to
into blocks!
context "first context" do travel_to("2024-12-25") do expect(presents) travel_to("2024-12-31") expect(fireworks) end end
- It's better to not write DSLs dynamically
This one might come as a surprise for some, because it sure did for me. Consider this example
describe 'some spec' do (1..7).each do |n| let!(:"user_#{n}") { create(:user, name: "user#{n}") } end # ... end
I thought I was super clever to use iteration like that, but learned from reviewers that it's not good practice. Although it saves time and works fine, it's not reader-friendly.
Instead, a very similar approach can be used through FactoryBot
describe 'some spec' do let!(:users) { FactoryBot.create_list(:user, 7) } # ... end
This obviously assumes that the name is set in the FactoryBot file
FactoryBot.define do factory :user do sequence(:name) { |n| "user#{n}" } # ... end end
As I become more acquainted with rspec and keep writing more code, I might come back and edit this document with more interesting finds ☺︎
Let's keep doing our best!
Top comments (0)