brandon.hornseth

Testing Controller Concerns with Minitest

tech

While RSpec is extremely popular in the Ruby community, I prefer to have less magic and better readability in my test suites. That means I use Minitest whenever I can.

There seems to be endless documentation for how to test Rails controller concerns with RSpec and little to none for Minitest so I decided to put together a quick writeup on how I’ve been going about it.

Let’s start with an example controller concern that sets a @current_user instance variable:

# app/controllers/concerns/user_context_concern.rb
module UserContext
  extend ActiveSupport::Concern

  included do
    before_action :set_current_user
  end

  def set_current_user
    @current_user = if session[:user_id]
                      User.find(session[:user_id])
                    else
                      NullUser.new
                    end
  end
end

Now let’s take a look at a simple test case for this module:

# test/controllers/concerns/user_context_concern_test.rb
require 'test_helper'

class UserContextConcernTest < ActionController::TestCase
  controller(ApplicationController) do
    include UserContextConcern

    # Create a simple action that renders text
    def index
      render plain: "Hello world"
    end
  end

  test "@current_user is a NullUser when session is empty" do
    get :index

    # this assertion would fail if an unhandled error occurred
    assert_reponse :success

    # Assert our controller concern code ran
    assert_instance_of NullUser, assigns(:current_user)
  end
end

This test creates an ephemeral controller class that includes our controller concern and an index method that simply renders a plain text response. The test case calls that index method, asserts we got a 200 OK reponse and the @current_user assignment is an instance of the NullUser class. That’s all there is to it!

Thanks for reading!

If you have any comments or feedback on this article, I’d love to hear from you. The best way to reach me is on Twitter.