How to stub a helper method?

Hi there

Lets say I have the following code on ApplicationController :

class ApplicationController < ActionController::Base
   helper_method :is_happy?

   private

   def is_happy?
      true
   end
end

and then, on my ApplicationHelper I have a method, which I would like to test like this:

def show_mood_text
  return 'Happy' if is_happy?

  'Sad'
end

I would like to test both cases, when is_happy? returns true and when it returns false . So, my option was to stub is_happy? method. For that, I did the following:

it 'returns Sad when when is sad' do
      allow(helper).to receive(:is_happy?).and_return(false)

      expect(helper.show_mood_text).to eq "Sad"
end

But when I try to run this test, I got the following error:

Failure/Error: allow(helper).to receive(:is_happy?).and_return(false)
       #<ActionView::Base:0x00000000009e70> does not implement: is_happy?

what am I missing here?

why not allow(ActionView::Base).to receive(:is_happy?).and_return(false)?

I already tried this option, I also tried allow_any_instance_of, unfortunately, it keep giving me the same error:

Failure/Error: allow(ActionView::Base).to receive(:is_happy?).and_return(false)
       ActionView::Base does not implement: is_happy?

Using allow_any_instance_of:

Failure/Error: allow_any_instance_of(ActionView::Base).to receive(:is_happy?).and_return(false)
       ActionView::Base does not implement #is_happy?

Ooops I misunderstood the error, maybe:

allow_any_instance_of(ApplicationController).to receive(:is_happy?).and_return(false)

Same problem. I keep getting:

NoMethodError:
       undefined method `is_happy?' for #<ActionView::Base:0x0000000000a960>

With a help, the only way I could make it work, was to create this method:

def inject_controller_helper_methods(controller_class)
    helper_module = (controller = controller_class.new)._helpers
    helper_methods = helper_module.instance_methods(false).sort
    helper_method = ->(method) { helper_module.instance_method(method) }

    helper_methods.each do |method|
      helper.class.define_method(method, helper_method[method])
    end

    helper.controller = controller
end

and on before block, do this:

before do
   inject_controller_helper_methods(ApplicationController)
end

It works, but feels like there could be a better solution.

Demo code: GitHub - weezhard0/demo-rails-rspec