How do you go about implementing and rspecing subdomains as account
keys? I’m sure that this must be an issues for others as well.
So I have an app using subdomains as account keys. The Application
Controller sets up @current_company in a before filter. Everything is
done within the context of the @current_company.
After reading about Demeter’s Revenge (http://www.lukeredpath.co.uk/
2007/10/18/demeters-revenge), and reading Sinclair’s advice (link
above), I refactored @current_company.items.find(:all) to
@current_company.find_items.
Still no luck. The spec fails with:
– Mock ‘Company’ expected :find_items with (:all) once, but received
it 0 times
The other thing that bugs me is the size of the setup method. It’s
getting too long and starting to smell. Obviously I must be making
this harder on myself that it needs to be.
Any ideas?
(This question was originally posted under “Mocking/Stubbing help
with subdomain as account key”
-
http://rubyforge.org/pipermail/rspec-users/2007-October/
004138.html, but I’ve rephrased it to make it more clear with the
subdomain as account key question.)
items_controller_spec.rb
describe ItemsController, “handling GET /items” do
fixtures :companies
before do
@request.host = “subdomain.test.host”
@item = mock(Item)
Item.stub!(:find).and_return([@item])
@current_company = mock(Company)
@current_company.stub!(:items).and_return([])
@current_company.stub!(:find_items).and_return([@item])
@current_company.stub!(:subdomain).and_return(“subdomain”)
end
# Passes
def do_get
get :index
end
# Passes
it “should be successful” do
do_get
response.should be_success
end
# Passes
it “should render index template” do
do_get
response.should render_template(‘index’)
end
FAILS with message:
Mock ‘Company’ expected :find_items with (:all) once, but
received it 0 times
it “should find all items” do
@current_company.should_receive(:find_items).with
(:all).and_return([@item])
do_get
end
Passes
it “should assign the found items for the view” do
do_get
assigns[:items].should == [@item]
end
end
items_controller.rb
class ItemsController < ApplicationController
def index
@items = @current_company.find_items(:all)
end
end
company.rb
class Company < ActiveRecord::Base
has_many :items
def find_items(*args)
items.find(*args)
end
end
application.rb
class ApplicationController < ActionController::Base
before_filter :find_current_company
def find_current_company
@current_company = Company.find_by_subdomain(account_subdomain)
end
end