Mike Mazur
2012-Mar-27 14:10 UTC
[rspec-users] Why stop using mock_model in scaffold controller spec?
Hi, In May last year, the controller specs generated with `rspec g scaffold` were changed to use real model objects instead of `mock_model`[1]. I''m curious why this change was made? Searching the rspec-users mailing list archives didn''t turn up anything, and rspec-devel archives I found finish in Februrary 2011[2]. Thanks, Mike [1]: https://github.com/rspec/rspec-rails/commit/daef552453e89616e2762e87c0a77dc9b08a2220 [2]: http://rubyforge.org/pipermail/rspec-devel/
Mike Mazur
2012-Mar-27 14:24 UTC
[rspec-users] Why stop using mock_model in scaffold controller spec?
Hi, On Tue, Mar 27, 2012 at 22:10, Mike Mazur <mmazur at gmail.com> wrote:> In May last year, the controller specs generated with `rspec g > scaffold` were changed to use real model objects instead of > `mock_model`. > > I''m curious why this change was made?As soon I sent this email off, I noticed this text in the template: # Compared to earlier versions of this generator, there is very limited use of # stubs and message expectations in this spec. Stubs are only used when there # is no simpler way to get a handle on the object needed for the example. # Message expectations are only used when there is no simpler way to specify # that an instance is receiving a specific message. That explains things a bit, but I''m still curious! One might argue that the earlier approach (with `mock_model`) may be better for at least two reasons: - looser coupling between specs and models - faster spec execution (ie: don''t have to create a real ActiveRecord instance) I imagine RSpec is treading the fine line between ideal "best practices" (ie: minimize coupling) and being more pragmatic and easier to understand by the average developer. What''s the current thinking on this topic? Thanks, Mike
David Chelimsky
2012-Mar-29 11:39 UTC
[rspec-users] Why stop using mock_model in scaffold controller spec?
On Tue, Mar 27, 2012 at 9:24 AM, Mike Mazur <mmazur at gmail.com> wrote:> Hi, > > On Tue, Mar 27, 2012 at 22:10, Mike Mazur <mmazur at gmail.com> wrote: >> In May last year, the controller specs generated with `rspec g >> scaffold` were changed to use real model objects instead of >> `mock_model`. >> >> I''m curious why this change was made? > > As soon I sent this email off, I noticed this text in the template: > > # Compared to earlier versions of this generator, there is very limited use of > # stubs and message expectations in this spec. ?Stubs are only used when there > # is no simpler way to get a handle on the object needed for the example. > # Message expectations are only used when there is no simpler way to specify > # that an instance is receiving a specific message. > > That explains things a bit, but I''m still curious! > > One might argue that the earlier approach (with `mock_model`) may be > better for at least two reasons: > > - looser coupling between specs and models > - faster spec execution (ie: don''t have to create a real ActiveRecord instance) > > I imagine RSpec is treading the fine line between ideal "best > practices (ie: minimize coupling) and being more pragmatic and easier > to understand by the average developer. What''s the current thinking on > this topic?It wasn''t really a loose coupling with models, it was a loose coupling with the underlying data. It was still very tightly coupled to ActiveRecord APIs (all, find, etc) because the generated controller code is coupled to those APIs. In rails-2, you could stub Model.find, and if you added constraints to find the specs would still pass because you were still using find. In rails-3, additional constraints are added via ARel APIs, which don''t end up going through find, so you have to change all the specs when you change the implementation. This created additional friction which was annoying to people who understood what was going on, and confusing for people who didn''t. In terms of the speed benefit, I do think that has merit and I stub model APIs all the time, but they are domain-specific APIs, not ActiveRecord APIs (most of the time). e.g. rather than stubbing Article.where("date >= ?", Date.today - 1.week) I''ll stub Article.recent and call that from the controller. This, however, is not something that a generator can do for you since it doesn''t know your domain. HTH, David