stubbing object.errors['base']

1 view
Skip to first unread message

Michael A

unread,
Oct 23, 2009, 5:43:25 PM10/23/09
to mocha-developer
I have a test that I need to stub out some objects in it. The model
does an add_to_base for specific error conditions and that is looked
at by another method to determine what to do based upon what errors
['base'] is set to. I need to test this other method but don't need
to go through the long operations that actually set errors['base']

I've been racking my head for a while trying to get this to work.
What I have is:

model = create_new_model
Model.any_instance.stubs(:do_something).returns(false)
model.stubs(:errors).returns({'base'=>'password'})
method.new(model.id).perform

Now what should be set is model.errors['base'] == 'password'

It is set in the test, but it isn't visible in method.perform (which
then calls do_something). In the perform method if model.do_something
== false I look at model.errors['base'] to determine what to do next.
But since model.errors isn't setup the test fails even though in the
real operating world it works out all fine.

Any ideas?

bcardarella

unread,
Oct 25, 2009, 12:54:53 PM10/25/09
to mocha-developer
I think you might need to call the stubbing of any instance before you
declare the model object:

Model.any_instance.stubs(:do_something).returns(false)
model = create_new_model
model.stubs(:errors).returns({'base'=>'password'})
method.new(model.id).perform

Just a guess

James Mead

unread,
Oct 26, 2009, 9:08:04 AM10/26/09
to mocha-d...@googlegroups.com
2009/10/23 Michael A <mall...@gmail.com>:

It's difficult to give you an answer without more details of the test
and the code under test, but I will have a guess. If these suggestions
don't work, then please send us more complete code for the test and
the code under test.

You need to be clear what instance of the model you are setting up the
stub on. It looks like the code under test is doing a database lookup
of the model you have created in create_new_model. Assuming you are
using ActiveRecord or something similar, the code under test will
obtain a different *instance* of the model which will not have the
stub set up on it. You seem to have realised this in the case of the
stub for the do_something method, because you are using any_instance,
but for the errors method you are not. There are a few ways of solving
this, here are a couple of ideas :-

1) Use any_instance for the errors stub :-

model = create_new_model
Model.any_instance.stubs(:do_something).returns(false)

Model.any_instance.stubs(:errors).returns({'base'=>'password'})
method.new(model.id).perform

2) Stub the database lookup and return the instance you have created
in the test (note that in this case you may no longer need to save the
instance to the database in create_new_model) :-

model = build_new_model
model.stubs(:do_something).returns(false)


model.stubs(:errors).returns({'base'=>'password'})

Model.stubs(:find).with(model.id).returns(model)
method.new(model.id).perform

Cheers, James.

Reply all
Reply to author
Forward
0 new messages