If I want to specify that the 'new' action in my
AccountsController assigns a new Account to @account, I'd
instinctively do this:
get :new
assigns[:account].should == Account.new
and expect this controller code to pass that code example:
def new
@account = Account.new
end
But this fails because ActiveRecord::Base doesn't treat new
records as equivalent (==), regardless of the values of their
attributes.
$ script/console
$ Account.new == Account.new
=> false
$ Role.new(:name => 'admin') == Role.new(:name => 'admin')
=> false
This means that the simple example above has to be more complex.
Here's the solution I see most often (in my code and in others,
regardless of testing and mocking frameworks used):
account = Account.new
Account.should_receive(:new).and(account)
get :new
assigns[:account].should == account
I think a reasonable approach would be to treat new records as
equivalent (==) as long as they are both new records and have
equivalent attributes (self.attributes == other.attributes).
This would make all of my rspec code examples much, much, much
cleaner and less brittle, and I'm quite sure I'm not alone.
Now I'll admit that changing the meaning of == might seem to
pose significant risk, but I made the change and the activerecord
unittest suite still passes. The change only affects new records,
and I can't imagine there would be many, if any, cases where
application code would actually behave differently due to this
change.
But that's just me :) I'm sure I'm not thinking of
something.
In any case, solution can be found at
http://github.com/dchelimsky/rai...>