I believe that let
, let!
and before
should be used for test setup, and after
should be used for test teardown. I also follow the Arrange, Act, Assert
test structure to organise my tests and make them easier to reason about.
Yesterday, during a code review, I tried to explain that to one of my co-workers. He wanted me to change this:
# made up code that I have
describe GameRetriever do
subject(:game_retriever) { described_class.new }
describe '#retrieve_games' do
it 'retrieves games from an HTTP data source', vcr: true do
games = game_retriever.retrieve_games
games = JSON.parse(games)
expect(games.first.keys).to eq(%w(id status players))
end
end
end
into this:
# his suggestion
describe GameRetriever do
subject(:game_retriever) { described_class.new }
let(:games) { game_retriever.retrieve_games }
let(:parsed_games) { JSON.parse(games) }
describe '#retrieve_games' do
it 'retrieves games from an HTTP data source', vcr: true do
expect(parsed_games.first.keys).to eq(%w(id status players))
end
end
end
He also suggested me to use after
to remove duplication in tests. I know that duplication is wrong, but I believe that it is not harmful in this scenario and it having the code explicitly written can make the code easier to understand:
# made up code that I have
describe StartGame do
let(:action) { described_class.new }
describe '#call' do
context 'when ...' do
expect(player).to be_playing
action.call
end
context 'when ...' do
expect(player).to be_idle
action.call
end
context 'when ...' do
expect(player).not_to be_playing
action.call
end
end
end
into this:
# what he suggested
describe StartGame do
let(:action) { described_class.new }
after { action.call }
describe '#call' do
context 'when ...' do
expect(player).to be_playing
end
context 'when ...' do
expect(player).to be_idle
end
context 'when ...' do
expect(player).not_to be_playing
end
end
end
Am I wrong in believing that this is the best way to structure our test suite or should I come up with better arguments?