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 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://rubyforge.org/pipermail/rspec-users/attachments/20080410/c79ea9ae/attachment-0001.html
On Thu, Apr 10, 2008 at 10:30 AM, Anthony Broad-Crawford <abroad-crawford at within3.com> wrote:> 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.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 Maddox 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.htmlFrom the linked post:> Also - right now it checks the hash against the model''s attributes. If > the model has a matching attribute it gets assigned, otherwise a stub > is created. It occurs to me that, with some modification, this *could* > be used as a bit of an auditing/red-flagging tool. So let''s say you do > this: > > stub_model(Person, :attrs => {:last_name => ''Name''}, :stubs => > {:full_name => ''Full Name''}) > > In this case it would fail if the Person model changed :last_name to > :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/ http://aviewfromafar.net/
On Thu, Apr 10, 2008 at 4:55 PM, Ashley Moran <ashley.moran at patchspace.co.uk> 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 Chelimsky 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 :D Ashley -- http://www.patchspace.co.uk/ http://aviewfromafar.net/