Pat Maddox wrote: > On Mon, Feb 9, 2009 at 10:18 PM, Sergio Bayona <li...@ruby-forum.com> > wrote: >>>> >> >> other is an AR object. But, shouldn't it return the mock property? >> []) >> respond_to do |format| >> got: #<Property id: nil, name: nil, address: nil, city: nil, state: >> nil, zip: nil, uasap: nil, tax_number: nil, rent_due: nil, units_count: >> 0, issues_count: 0, account_id: 1, created_at: nil, updated_at: nil> >> (using ==) >> -- >> Posted via http://www.ruby-forum.com/. >> _______________________________________________ >> rspec-users mailing list >> rspec-users@rubyforge.org >> http://rubyforge.org/mailman/listinfo/rspec-users >> > > Hi in your new method, where does @account come from? Is it loaded > through some kind of before_filter, or as part of the authentication > framework? > > Anyway, once you've built up your mock expectations you now need to > inject the mock into the code. You do this by stubbing the code that > loads up the @account object - typically you're just doing an > Account.find call somewhere. Note also that you need to specify that > account returns something when properties is called - you need to hook > up the association proxy. > > it "should expose a new property as @property" do > @account = mock_model(Account) > Account.should_receive(:find).with("1").and_return @account > @account.stub!(:properties).and_return mock('properties proxy') > @property = mock_model(Property, :new_record? => false, :errors => > []) > @account.properties.should_receive(:build).and_return(@property) > get :new > assigns[:property].should == @property > end > end > > additionally I would only have two expectations (should_receive) and > would loosen the rest by just stubbing: > > it "should expose a new property as @property" do > # arrange > @account = mock_model(Account, :properties => mock('properties > proxy')) > @property = mock_model(Property, :new_record? => false, :errors => > []) > @account.properties.stub!(:build).and_return(@property) > > # sanity check > Account.should_receive(:find).with("1").and_return @account > > # act > get :new > > # assert > assigns[:property].should == @property > end > end > > I like to minimize the number of expectations(/assertions) that appear > in the example. Doing so clearly communicates the important behavior. > If the final expectation passes, you can infer that it's doing the > right thing with the model because that's the only way to get to your > mock @property. Finally I threw in an Account.should_receive("1") > because you need to inject the mock account somehow. That does the > trick, and it also serves as a sanity check for the contract between > controller and model - Account.find is the entry point to the model in > this action. > > Does that make sense? > > Pat
Thanks Pat. You're right. Account comes from a before_filter that triggers this: def current_account @account ||= Account.find_by_subdomain(account_subdomain) end I have stubbed the code on the spec_helper.rb to do that as: def current_account(account) @controller.stub!(:current_account).and_return(@account = account ? accounts(account) : nil) #should return account fixture end on the property spec now I have: describe PropertiesController do fixtures :accounts, :properties, :users before(:each) do current_account(:default) login_as(:default) end describe "responding to GET new" do it "should expose a new property as @property" do property = mock_model(Property, :new_record? => false, :errors => []) @account.properties.should_receive(:build).and_return(property) get :new assigns[:property].should == property end end end but now the controller complains that @account is nil: The error occurred while evaluating nil.properties /www/rentcloud2/app/controllers/properties_controller.rb:23:in `new' I thought by stubbing the current_account code and returning @account, that'd be available to the application. -- Posted via http://www.ruby-forum.com/. _______________________________________________ rspec-users mailing list rspec-users@rubyforge.org http://rubyforge.org/mailman/listinfo/rspec-users