jdune jdune - 4 months ago 8x
Ruby Question

RSpec mocking module function of controller

So I'm very new to Rails and struggling a bit with RSpec, specifically mocking certain things. So I have a module (concern) that a few of my controllers are using. That module (ValidateAdmin) calls two other functions within, current_user and logged_in_user. To cover the most possibilities, I wanted to stub both those functions and set their return value. Any suggestions on how to make this work?

describe ValidateAdmin do
before :all do
class FakeController < ApplicationController
include ValidateAdmin

let(:controller) { FakeController.new }

describe '#validate_admin_logged_in' do
controller.stub(:current_user).and_return(instance_double(User, admin?: true))
controller.stub(:logged_in_user).and_return(instance_double(User, admin?: true))
[RSpec contexts go here]

Edit - Fixed it by containing my mocking statements inside a 'before' block. Also just realized stub is deprecated so switched to allow statements.


The controller instance can be stubbed like any other object. You may also need to add the route:

describe FakeController, type: :controller do
  let(:admin_user) { instance_double(User, admin?: true) }

  it "performs my excellent test" do
    allow(controller).to receive(:current_user).and_return(admin_user)
    routes.draw { get "custom_action" => "fake#custom_action" }
    get :custom_action

let(:controller) is uneccessary -- RSpec does that for you. Also, the test class does not need to go into a before block -- it can simply be defined at the top of the file, or require-d.