0
votes

So my setup is that I have my Rails application that makes use of a certain gem that I'm also developing. Right now I'm writing some unit tests for the gem's helpers in RSpec. The gem cannot run by itself and is loaded by my application, so when testing it's loaded by a 'dummy' application that replicates many of the functions provided by the application to the gem.

One of the methods in my gem's helpers calls a helper method defined in my (dummy) application's ApplicationController, like so:

Method in gem:

module MyGem::ApplicationHelper
    ...

    def method_to_test()
        #do stuff
        x()
        #do other stuff
    end

    ...

end

Here's how the test would be constructed for the method:

describe MyGem::ApplicationHelper do
    ...

    describe "#method_to_test()" do
        it "should do x" do
            expect( method_to_test() ).to do_stuff
        end
    end

    ...

end

And here's the method in the (dummy) application:

class ApplicationController < ActionController::Base
    ...

    helper_method :x
    def x()
        # do stuff
    end

    ...

end

The problem is that when I run the test, I get the following error:

NoMethod error: undefined method 'x' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_7:0x24ef2645>

I've tried stubbing the method with:

ApplicationController.any_instance.stub(:x)

But I still get the same error. I've done more troubleshooting, but the only idea I can think of is that the ApplicationController that houses the helper method isn't getting loaded by RSpec in the first place.


EDIT: I found out that I can't even stub a method from the same helper I'm working on, e.g.

module MyGem::ApplicationHelper
    ...

    def method2()
        #do stuff
    end        


    def method1()
        #do stuff
        method2()
        #do other stuff
    end

    ...

end

If I write this in my test:

describe MyGem::ApplicationHelper do
    ...

    describe "#method1()" do
        it "should do x" do
            helper.stub(:method2).and_return(false)
            #or:
            helper.should_receive(:method2).and_return(false)

            expect( method1() ).to do_stuff
        end
    end

    ...

end

I get the same behaviour as my initial problem. I am so confused right now :/

1

1 Answers

0
votes

So apparently I should call my helper methods with helper., with a 'stub' in the before block. So instead of doing this:

expect( method_to_test() ).to do_stuff

I should be doing this:

expect( helper.method_to_test() ).to do_stuff

With this in the test's before block:

controller.singleton_class.class_eval do
    helper_method :x
    def x()
        #do stuff
    end
end

In addition, sometimes I get weird errors that I fix by pulling out the helper.method_to_test() out into a local variable like so:

test_result = helper.method_to_test()
expect( test_result ).to do_stuff

I'm not sure why the variable 'trick' works, but it does so I can't complain! As for the helper. prefix, I think that without it RSpec doesn't call the method from the helper instance itself that's being tested. I'm not sure why it didn't fail with a NoMethodError, though.