Testing Shared Modules and ActiveSupport Concerns

Learn about shared behavior, testing shared modules, shared directory, shared examples, invoking shared behavior, and ActiveSupport concerns.

Shared behavior

Often multiple models in the application share some common feature set.

For example, we may have multiple object types that can be:

  • Purchased
  • Tagged
  • Commented on

We can use standard Ruby classes and modules for this shared behavior. If the shared behavior has both class and instance methods, Rails provides ActiveSupport::Concern, which allows us to easily use a common pattern to mix multiple kinds of behavior from one module.

Testing shared behavior

Testing this shared behavior can be a challenge. We don’t want to rewrite the shared behavior specs for each class that shares the mixed-in module. Simultaneously, if the shared feature depends on data being available in each class, that dependency is testable logic.

Sharing specs

RSpec has a powerful mechanism for sharing specs across multiple objects with common functionality, called the shared example. We can use shared examples to run the same set of specs in multiple describe blocks, whether the common feature is encapsulated in a module or not.

  • Shared examples in RSpec have two parts: definition and usage.

The shared directory

Shared examples must be defined before they’re used. In a Rails context, the easiest way to do that is to put the shared examples inside a spec/shared directory and then add this line to the Rails rails_helper.rb file to load everything in that directory before any specs are run:

Dir[Rails.root.join("spec/shared/**/*.rb")].each { |f| require f }

Let’s create a contrived example. Suppose we want projects and tasks to respond to a similar set of adjectives about their size. Here a shared group is created, with the method shared_examples taking a string argument and a block:

Get hands-on with 1200+ tech skills courses.