Blankman
Blankman

Reputation: 267320

How to test the AdminController when it has no actions?

My AdminController looks like:

class AdminController < ApplicationController
  before_action :check_admin

  private
    def check_admin
      redirect_to 'home/error' unless current_user.admin?
    end

end

In my rspec test, how can I test this if there are no route or views?

require 'rails_helper'

RSpec.describe AdminController, type: :controller do
  context "with no render_views" do
    it "redirects for non-admin users" do
        #???expect do
    end
    end
end

Upvotes: 0

Views: 173

Answers (1)

harimohanraj
harimohanraj

Reputation: 99

I am assuming that you are using a before_action in your AdminController, even though this controller does not have any actions, so that any controllers that inherit from it will automatically by "admin only".

If so, there are two ways to approach testing this.

1) Don't write a test for check_admin.

Instead, write tests for any controller actions that you define later! For example, if you have the following controller in your application tomorrow:

UsersController < AdminController
  def index
    @users = User.all
  end
end

then you can write the following specs for that controller.

describe UsersController
  it 'redirects for non-admins' do
    # insert the test you feel like writing here!
  end

  it 'renders the right template for admin users' do
    magical_login_method
    get :index
    expect(response).to render_template(:index)
  end
end

and so on!

2) Call the private method directly

This approach makes me feel a bit icky. Although this defeats the philosophy of public vs private methods, you can call a private method in ruby by using the .send method.

describe AdminController
  it 'redirects for non-admins' do
    # make an instance of your controller
    controller = AdminController.new

    # expect the controller to call `redirect_to`
    expect(controller).to receive(:redirect_to).with('home/error')

    # call the private `check_admin` method
    controller.send(:check_admin)
  end
end

Some, perhaps many, would argue that this sort of testing is highly intrusive, and may even limit the flexibility of your codebase in the future. I'd recommend approach 1, not because it's lazy, but because it tests things once there's something to test!

Upvotes: 1

Related Questions