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)