Sharing Code Conditionally

In Chapter 7, Structuring Code Examples, we discussed three ways to share code across many example groups:

  • Top-level config hooks
  • Modules containing helper methods
  • Shared contexts containing RSpec constructs (such as hooks and let blocks)

You’ve used all of these techniques throughout this book. By default, they all share code unconditionally. If you define, say, a before hook in your RSpec.configure block, the hook will run for every example.

Often, though, you want to use a certain bit of shared code only for specific examples. For instance, in Isolating Your Specs Using Database Transactions, you defined an around hook to wrap a database transaction around only the examples tagged with :db:

 c.around(​:example​, ​:db​) ​do​ |example|
  DB.transaction(​rollback: :always​) { example.run }
 end

Metadata is what enables this flexibility, and you can use it with all of the code-sharing techniques listed earlier. Here’s how:

Config hooks

Pass a filter expression as the second argument to config.before, config.after, or config.around to run that hook only for examples matching the filter.

Modules

Add a filter expression to the end of your config.include call in order to include a module (and its helper methods) conditionally. This also works with RSpec’s similar config.extend and config.prepend methods, which are covered in the docs.[58]

Shared contexts

Just as with modules, add a filter expression when calling config.include_context. This will bring in your shared let constructs (among other things) into just the example groups you want.

All the techniques in this section help you selectively share behavior among your examples, based on metadata. Before we wrap up this chapter, let’s take a look at one more way to use RSpec metadata: to control how your specs run.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset