Let's say that we have this spec structure:
require 'rails_helper'
describe 'search_index' do
context 'entity A' do
let(!setup_a){ create :a}
...
before do
SearchIndex.delete! rescue nil
SearchIndex.create
SearchIndex.import
end
...
end
...
context 'entity B' do
let(!setup_b){ create :b}
...
before do
SearchIndex.delete! rescue nil
SearchIndex.create
SearchIndex.import
end
...
end
let(!setup_b){ create :b}
...
before do
SearchIndex.delete! rescue nil
SearchIndex.create
SearchIndex.import
end
...
end
end
As we see the before blocks are the same. Some might be tempted to move to a common place.
Let's do this:
describe 'search_index' do
before do
SearchIndex.delete! rescue nil
SearchIndex.create
SearchIndex.import
end
...
...
end
...
context 'entity B' do
...
...
end
...
...
end
end
If we take a closer look we can easily identify the spot.
The import in the before blocks was run before the setup_b and setup_a was called. So there was nothing to import therefore our expectations run on an empty index.
In this particular case it was much more beneficial to leave the common code where it is.
But wait... Aren't we dealing with a ruby code? Yes of corse. This means that the content of the before can be extracted into a function then called before any context.
require 'rails_helper'
def reinitialise_the_index
SearchIndex.delete! rescue nil
SearchIndex.create
SearchIndex.import
end
describe 'search_index' do
context 'entity A' do
let(!setup_a){ create :a}
...
before do
reinitialise_the_index
end
...
end
...
context 'entity B' do
let(!setup_b){ create :b}
...
before do
reinitialise_the_index
end
...
end
let(!setup_b){ create :b}
...
before do
reinitialise_the_index
end
...
end
end
Much simpler isn't it?
Happy coding :)
Happy coding :)