[mocha-developer] Login systems : stubbing accounts and AR association proxies

James Mead jamesmead44 at gmail.com
Tue Feb 6 09:33:40 EST 2007

On 06/02/07, Jonathan del Strother <maillist at steelskies.com> wrote:
> My Rails site has a fair amount of login and 'ownership' logic.  For
> instance, we have a number of clients (companies), each of which has
> several accounts.  A client owns a number of different types of
> resources, and shouldn't see any other clients' resources, so, for
> example, our ScenesController contains a lot of references to
> 'current_client.scenes', rather than Scene.find(:all)
> All of which works pretty well, but it can make testing very
> tedious.  I always need to set up a fake client, and a fake account,
> and log in with that account, and make sure that whatever resource
> I'm dealing with in that unit test is assigned to the fake client,
> and so on.
> I'm starting to wonder whether I ought to stub all the login and
> ownership logic out of my functional tests, so I can concentrate on
> whatever resource I'm dealing with in that given test.  All the login/
> ownership stuff could be handled in integration testing, which is
> probably better suited to it anyway, due to having real sessions etc
> etc.
> I'm having difficulty doing so, however.  The controller uses some
> current_account / current_client methods to find whoever's logged in
> - stubbing those to return a fake client/account is easy, but you're
> then left with problems with Rails' association proxies.  There's
> lots of use of things like  current_client.scenes.build, which are
> not so easy to stub out (particularly as, AFAICT, you can't make use
> of any arguments passed into a stubbed method).
> Has anyone else done anything similar, or am I just creating more
> work for myself by trying to remove login details from functional
> testing?

I think your motivation is good. We have run into similar issues with
association proxies.

Rails association proxies encourage train-wreck code / violations of the Law
of Demeter (http://en.wikipedia.org/wiki/Law_of_Demeter).

We've tended to introduce public methods on the parent class which delegate
to their proxies. Then you can then stub the newly introduced methods. So in
your case a simple version would be...

class Client < ActiveRecord::Base

  has_many :scenes

  def build_scene


Then you can stub Client#build_scene.

My colleague Chris Roos has some thoughts on this subject here...


More information about the mocha-developer mailing list