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
Ashley
–
http://www.patchspace.co.uk/