Mock_model

Our company just had an interesting conversation around mock_model and
I want to ask the same question to this audience. When creating
mock_models what is the purpose of passing in the class constant?

user = mock_model(User)

To the best that we can tell the method mock_model doesn’t actually
use the class for anything. Please correct us if we are wrong.
Secondly, we also typically after a mock_model stub the necessary
properties (attributes) that are accessed off of the model. For
example …

user = mock_model(User)

user.stub!(:username) …
user.stub!(:password) …

Why doesn’t mock model interrogate the attributes and generate these
mocks for me? Thanks for taking the time to answer.

Anthony Broad-Crawford

On Thu, Apr 10, 2008 at 10:30 AM, Anthony Broad-Crawford
[email protected] wrote:

user = mock_model(User)

user.stub!(:username) …
user.stub!(:password) …

Why doesn’t mock model interrogate the attributes and generate these mocks
for me? Thanks for taking the time to answer.

mock_model does a little bit of stuff for you. It generates a unique
ID for the object, sets new_record? to false, and gives it an empty
errors array. Not much else though.

stub_model, available in RSpec trunk, may be more to your liking. You
can read about it at
http://rubyforge.org/pipermail/rspec-devel/2008-March/004782.html

Pat

On 10 Apr 2008, at 18:54, Pat M. wrote:

stub_model, available in RSpec trunk, may be more to your liking. You
can read about it at
http://rubyforge.org/pipermail/rspec-devel/2008-March/004782.html

From the linked post:

:given_name, for example. I have very mixed feelings about that, and
might never use it myself, but it would serve to alleviate the fear of
false positives.

On my last job I extended my client’s Factory class so you could
create either real or mock objects with a stub list. The syntax was
(uses method missing for the “model_name” bit):
Factory.mock_model_name(:name => “Fred”, :age => 25)

This was against a pure mock (generated from mock_model) so there was
no issue with attrs vs stubs. What it did do, however, was something
like (from memory):
raise “Useful error message” unless model_class.new.respond_to?(stub)

I also created another version,
Factory.mock_model_name!(attrs)

which printed to STDERR instead of raising an exception. (The !
implying “unsafe” rather than "raises an exception.) While I was
using it I found the stub checking REALLY useful (I never used the !
version myself) - it caught a few cases where I had changed or not
added a model method.

David: +1 for stub_model, but could you make it autodetect if the stub
is for an attribute or a method? It would be nice to do away with
the :attr and :stub distinction. I have to say, though, I don’t see
the advantage of using a real object as the basis for the mock as long
as one is used as a sanity check for the stubs (maybe I am missing a
benefit).

Ashley


http://www.patchspace.co.uk/

On Thu, Apr 10, 2008 at 4:55 PM, Ashley M.
[email protected] wrote:

David: +1 for stub_model, but could you make it autodetect if the stub
is for an attribute or a method? It would be nice to do away with
the :attr and :stub distinction.

Not sure what you mean here - that is handled transparently by
stub_model so you don’t have to make any such distinction. Take a look
at
http://github.com/dchelimsky/rspec-rails/tree/master/lib/spec/rails/example/rails_example_group.rb
and see if it sheds some light.

I have to say, though, I don’t see
the advantage of using a real object as the basis for the mock as long
as one is used as a sanity check for the stubs (maybe I am missing a
benefit).

Not sure what you mean here either. Can you elaborate?

On 10 Apr 2008, at 22:28, David C. wrote:

Not sure what you mean here - that is handled transparently by
stub_model so you don’t have to make any such distinction. Take a look
at http://github.com/dchelimsky/rspec-rails/tree/master/lib/spec/rails/example/rails_example_group.rb
and see if it sheds some light.

So it does - the code in the previous post was this, however:

stub_model(Person, :attrs => {:last_name => ‘Name’},
:stubs => {:full_name => ‘Full Name’})

Where did :attrs and :stubs go? (or come from?)

I have to say, though, I don’t see
the advantage of using a real object as the basis for the mock as
long
as one is used as a sanity check for the stubs (maybe I am missing a
benefit).

Not sure what you mean here either. Can you elaborate?

Just that you have the line
model_class.new do |model|

Where I did
mock_model(model_class)

then later when stubbing did something like
stubs.each { |msg, ret|
… raise unless model_class.new.respond_to?(msg) }

This gives you the advantage of checking the stubs against a real
model but on a “pure” mock. I just wasn’t sure what the advantage of
using a partial mock was, in this case.

As for the comment:

    #--
    # TODO - Shouldn't this just be an extension of stub! ??
    # - object.stub!(:method => return_value, :method2 =>  

return_value2, :etc => etc)
#++

+1 on that too. I’ve wanted that for so long :smiley:

Ashley


http://www.patchspace.co.uk/