0

In my application_controller.rb:

helper_method :current_brand
def current_brand
  @brand ||= Brand.find_by_organization_id(current_user.organization_id)
end

In my helper something_helper.rb

def brands
  return [] unless can? :read, Brand
  # current_brand is called
end

I am writing a spec for something_helper and wish to stub current_brand

describe SomethingHelper do
  before :each do
    helper.stub!(:can?).and_return(true) # This stub works
  end

  it "does the extraordinary" do
    brand = Factory.create(:brand)
    helper.stub!(:current_brand).and_return(brand) # This stub doesnt work
    helper.brands.should_not be_empty
  end
end

Results in NameError: undefined local variable or method 'current_brand' for #<#<Class:0x000001068fd188>:0x0000010316f6f8>

I have tried doing the stub! on self and controller as well. Strangely, when I stub on self, the helper.stub!(:can?).and_return(true) gets unregistered.

Brad
  • 5,428
  • 1
  • 33
  • 56
  • It looks like `#current_brand` isn't a method on your helper, but instead is a method in your controller. Can you move this method into the SomethingHelper? – Jesse Wolgamott Nov 03 '11 at 18:44
  • Jesse, I _could_ but I would rather not as `current_brand` is used by both the controller and view. When `#current_brand` is defined on the helper directly, the tests pass. – Brad Nov 03 '11 at 19:39
  • What does current_brand do? what inputs does it take to make its decision? – Jesse Wolgamott Nov 03 '11 at 20:32
  • I updated the question to include the implementation. It simply returns the brand belonging to the user. Normally I would make this a method directly on the user (`User#brand`) but the two are in separate engines and stored in different databases. – Brad Nov 03 '11 at 20:37

2 Answers2

1

OK, how about something else... You're really asking Brand.for_user

So:

class Brand
  ...
  def self.for_user(user)
    find_by_organization_id(user.organization_id)
  end
end

Then, you'd just:

brand = mock(Brand)
Brand.stub(:for_user => brand)

Or something similar... If you extract that logic out to something that is easily stubbable, it'll make things easier. A Presenter class, perhaps, or this static method.

Jesse Wolgamott
  • 40,197
  • 4
  • 83
  • 109
  • Yea, this is probably what I will end up doing. The one thing I like about it being as a controller helper is that it is scoped by the request. So I can have @current_brand and only look it up once. Of course, I can do this with the static method as well, but its not as clean. I am going to leave the question up a bit longer before accepting. – Brad Nov 03 '11 at 22:02
  • You could still do this and stub the new method instead of current_brand. `def current_brand @brand ||= Brand.for_user(current_user) end` – Jesse Wolgamott Nov 04 '11 at 14:11
  • I ended up creating a mixin for the User model so I can just call current_user.brand. Thanks for putting me on the right path though! – Brad Nov 04 '11 at 15:36
0

Have you tried something similar to:

ApplicationController.stub!(:current_brand).and_return(brand)

Jesse Wolgamott
  • 40,197
  • 4
  • 83
  • 109
fuzzyalej
  • 5,903
  • 2
  • 31
  • 49