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!