Testing Email Deliveries using Cucumber/Capybara/Minitest

# features/support/env.rb
Around('@email') do |scenario, block|
  ActionMailer::Base.delivery_method = :test
  ActionMailer::Base.perform_deliveries = true

  old_adapter = ActiveJob::Base.queue_adapter
  ActiveJob::Base.queue_adapter = :inline
  # ActiveJob::Base.queue_adapter.perform_enqueued_jobs = true

  ActiveJob::Base.queue_adapter = old_adapter

# features/steps/*_step.rb

Then(/^I should receive an email$/) do
  # assuming mailcatcher
  assert_difference -> { ActionMailer::Base.deliveries.length } do
    # do stuff that is supposed to send an email

# features/*.feature

Scenario: Checkout page
  When I press the checkout button
  Then I should receive an email

Minitest with Kaminari

While converting my tests from FactoryGirl.create to FactoryGirl.build_stubbed, I ran into trouble with Kaminari. Here’s how I fixed it.


Kaminari functions by adding .page() (and some other methods) at the end of your ActiveRecord call chain. A typical example of paginating via Kaminari is as follows:

class UsersController < ApplicationController
  def active_users
    @users = User.active_users.page(params[:page])

This is a problem when you’re trying to stub out the return of the AR call to return an array. Here’s a corresponding test that would fail:

require 'test_helper'

describe UsersController, "#active_users" do
  test "success" do
    users = FactoryGirl.build_list :user, 3
    get :search, term: "admin_user"
    assert_response :success

Because users is just a regular array here, and Kaminari tries to call .page() on the array, it would fail with a NoMethodError: undefined method `page’ for # because Array#page isn’t defined.

Trying to stub out .page() by users.stubs(page: users) would give you ActionView::Template::Error: undefined method `model_name’ for #. And so on, as long as you’re using Kaminari-specific methods.

The solution

The solution is pretty simple (but took me 2+ hours to research). Call Kaminari.paginate_array on the FactoryGirl.build_list.

users = Kaminari.paginate_array FactoryGirl.build_list :user, 3

From the documentation:

Kaminari::paginate_array method converts your Array object into a paginatable Array that accepts page method.

For now, I’m putting the Kaminari.paginate_array inside the test, but long term, it makes sense to put it in the controller code. This way, even if we change User.active to return an array, no other code would break. Then again, that’s why we have tests, right?