A couple of weeks back, I was working on some RSpec tests that required a different setup and tear-down than other tests in the app. We had “database cleaner”:https://github.com/bmabey/database_cleaner providing cleanup for us to prevent test interaction, but certain tests we created needed a heavier cleanup than others. We had a simple
after(:each) with the setup and tear-down, but that had to change to accommodate certain types of tests.
We have defined RSpec metadata on certain tests that need extra attention in the setup or tear-down stages like so:
This allows us to filter (“RSpec filtering in before/after hooks”:https://www.relishapp.com/rspec/rspec-core/v/2-13/docs/hooks/filters) the tests with type
:spec_type in our spec_helper.rb file. The
:spec_type is arbitrary in this case, it could be anything (
:things_need_more_cleaning, etc). In our spec_helper.rb we can now target these tests for extra work with befores and afters:
Looking back at our project, we had a few of these guys set up to provide database cleanup between tests, but they didn’t care about the test type — we had only one need fore cleanup. After introducing a couple of new test types, we had need for different cleanup methods, so we would have written this:
This example shows a general setup for any test type, but for some cases of test types it had some special hooks. In this case, the
:fancy_type shared the same setup and tear-down — not very DRY, huh? After a little looking, we found the RSpec around hook.
RSpec Around Hook Explained
The “around hook”:https://www.relishapp.com/rspec/rspec-core/v/2-13/docs/hooks/around-hooks allows us to DRY up the setup and tear-down of our tests. DRYing up the tests is not the only thing
around() lets us do; it also allows us to wrap our before and afters with another layer of setup/teardown. This is how we came out:
Our sample would run in this order:
# around each setup (general or special setup — dependent on the if statement)
# before each
# the actual spec
# after each
# around each tear-down (general or special tear-down — dependent on the if statement)
There are plenty of possibilities with the around, before, and after hooks, especially since they can be targeted to all tests, a suite of tests, and each test.