Pat Maddox wrote:
> On Mon, Feb 9, 2009 at 10:18 PM, Sergio Bayona <[email protected]>
> 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
>> [email protected]
>> 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
[email protected]
http://rubyforge.org/mailman/listinfo/rspec-users