Stubbing out a method from a module in Rspec - ruby-on-rails

In my rails project I have a presenter method that has a helper view method in it. This helper method is already tested so I would like to stub out it out in my test. How may I write this in my spec.

If you're trying to stub it in your view spec then how about something like this:
before(:each) do
view.stub!(:my_helper).and_return(something)
end

Related

How do you stub and test a helper that invokes a different method depending on the object class passed to it?

I've got this helper which I'm trying to write tests for in Minitest. The helper calls another method depending on the object class I'm passing as an argument, like so:
def label_for(object)
status = object&.status
case object.class.name
when "Subscription"
class_for_subscription_status(status)
when "Payment"
class_for_payment_status(status)
when "Purchase"
class_for_purchase_status(status)
when "Invoice"
class_for_invoice_status(status)
when "Ticket"
class_for_ticket_status(status)
end
Each individual method is already tested somewhere else, so I just need to test that if I pass a class Subscription object to label_for, it will invoke class_for_subscription_status(status) and not something else.
This is the test I've come up with, but I get NoMethodError: undefined method ``class_for_subscription_status' for #<AuxiliariesHelperTest errors.
test "#label_for(object) should invoke the right helper if object is of class Subscription" do
AuxiliariesHelperTest.any_instance.stubs(:label_for).with(subscriptions(:user)).returns(:class_for_subscription_status)
assert_equal class_for_subscription_status(subscriptions(:user).status), label_for(subscriptions(:user))
end
What am I doing wrong?
Could you add the whole classes? Is a little bit hard to guess with just this snippet.
One of the problems I see is that you are stubbing a method from the AuxiliariesHelperTest class, instead of the AuxiliariesHelper class.
Another possible issue is that your helper seems to be a module and not a class, and you should include the helper in your test file. Or your test class should inherit from ActionView::TestCase. Something like this might help:
class AuxiliariesHelperTest < ActionView::TestCase
include AuxiliariesHelper
test "#label_for(object) should invoke the right helper if object is of class Subscription" do
AuxiliariesHelper.any_instance.stubs(:label_for).with(subscriptions(:user)).returns(:class_for_subscription_status)
assert_equal class_for_subscription_status(subscriptions(:user).status), label_for(subscriptions(:user))
end
end
Although in my opinion, you should not stub the method, but expect that the correct method is called:
class AuxiliariesHelperTest < ActionView::TestCase
include AuxiliariesHelper
test "#label_for(object) should invoke the right helper if object is of class Subscription" do
AuxiliariesHelper.any_instance.expects(:label_for).with(subscriptions(:user).status)
label_for(subscriptions(:user))
end
end

Rspec: stubbed model method still being called in controller test

In have this model in Rails:
class User < ActiveRecord::Base
def self.create_auth_from_hash(hash)
# stuff
end
end
I want to stub the create_from_auth_hash method so I can isolate the controller behaviour. Apparently the current syntax for this is:
expect_any_instance_of(User).to receive(:create_from_auth_hash).and_return(false)
But even though I get no errors, the model method is still called.
How can I stub model methods? I'm using Rails 4.1 and RSpec 3.0.
Your expectation is set up to stub a method on any instance of User, not the class method you've defined on User.
To do that, you just pass User as the argument to expect, instead of an instance. Like this:
expect(User).to receive(:create_from_auth_hash).and_return(false)

How to test a Rails helper that depends on another Rails helper?

I am writing an RSpec spec to test a Rails helper. The problem is that the helper method that I'm testing depends on a method defined in a different helper. It may be a code smell to me, but I'm adding tests for legacy code and am not at a point where I can refactor. How can I test this Rails helper?
module FancyHelper
def fancy_method
html = "hello"
html << another_fancy_method
html
end
end
module OtherHelper
def another_fancy_method
"world"
end
end
require "spec_helper"
describe FancyHelper do
describe "#fancy_method" do
it "does what it's supposed to" do
helper.fancy_method.should match("hello")
# NoMethodError: undefined method `another_fancy_method'
end
end
end
This is what stubs are for. When testing your helper that depends on the other helper, you will want to stub the other helper to get a predictable value and complete the test.
EDIT: https://www.relishapp.com/rspec/rspec-mocks/docs/method-stubs thanks grantovich for the newer link.

Stub a controller helper method in a template helper spec

My ApplicationController exposes a method (e.g. sort_direction) to the view templates by using helper_method :sort_direction. I then use this method in another method (e.g. sort_link) of a view helper (application_helper.rb).
When testing the sort_link method with RSpec (in application_helper_spec.rb) I have to stub sort_direction as the test seems to run complete independent from the controllers (and thereby by its to the view templates exposed methods).
Unfortunately I could not find out how to stub that sort_direction method of the controller. I always get "undefined method".
Here is what I tried so far (inside application_helper_spec.rb):
helper.stub(:sort_direction)
controller.stub(:sort_direction)
view.stub(:sort_direction)
self.stub(:sort_direction)
Any suggestions how I can stub that method?
Here the error I get:
NoMethodError:
undefined method `sort_direction' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_1:0xb641434c>
David Chelimsky solved that problem here: http://groups.google.com/group/rspec/browse_thread/thread/cc44ca12c6816053
Simply call in the spec all methods on the helper object:
it "should work" do
helper.stub(:sort_direction)
helper.sort_link(...).should == ...
end

Adding Controller Macros in Rspec

Im trying to define some controller macros for Rspec. Im using rails 3 and have my macros defined in spec/support/macros/controller_macros.rb, that file looks like this:
module ControllerMacros
def self.login_admin
#code
end
end
in my spec helper I have:
config.include(ControllerMacros, :type => :controller)
So in my controller spec i just call login_admin in my admin tests but when ever i use the method i get
undefined local variable or method `login_admin' for #<Class:0xb6de4854> (NameError)
At first I assumed that controller_macros.rb wasn't being included but when I added a "puts" to the file but that showed the file was at least being executed.
I can't see anything wrong with my setup and copying the login_admin method into the describe block works fine so im not sure whats wrong with it.
Maybe I am late to that, but for new comers.
Here is a good examples of using macros:
http://osmose.6spot.com.br/2011/01/rails-resource-routing-spec-w-rspec/
when you include a module it's methods are visible inside examples.
But when you extend the module, it's methods are only visible outside examples.
It gives you ways to compose your macros for each situation.
Try
ControllerMacros.login_admin
or remove self from the method definition.
One line answer: Remove self from the method definition
Why? The methods of included modules are available in RSpec examples
The login_admin method defined in ControllerMacros will be available in your RSpec example as login_admin
To Be Specific:
Rewrite spec/support/macros/controller_macros.rb as
module ControllerMacros
def login_admin
#code
end
end
Then tell Rspec to include the Macros
config.include(ControllerMacros, :type => :controller)

Resources