Stubbing chained methods

1,846 views
Skip to first unread message

apneadiving

unread,
Jun 28, 2011, 7:27:27 PM6/28/11
to Jasmine
Hi,

Currently, I successfully use Spies for foo.bar like this: spyOn(foo,
"bar").andReturn("yo")

Now I'd like to stub chained methods like: foo.bar.baz

Is this possible?

Marc Chapman

unread,
Jun 28, 2011, 7:44:21 PM6/28/11
to jasmi...@googlegroups.com
I've done it by doing something to the effect of....

speyOn(foo.bar, "baz").andReturn("yo")

but in this case, bar needs to be an object as well as foo.



--
You received this message because you are subscribed to the Google Groups "Jasmine" group.
To post to this group, send email to jasmi...@googlegroups.com.
To unsubscribe from this group, send email to jasmine-js+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/jasmine-js?hl=en.


Marc Chapman

unread,
Jun 28, 2011, 7:44:37 PM6/28/11
to jasmi...@googlegroups.com
I've even done it with spyOn rather than speyOn.

Rajan Agaskar

unread,
Jun 28, 2011, 8:51:40 PM6/28/11
to jasmi...@googlegroups.com
Yes, if we're talking about something like a namespaced object (ie, you'd call this method like: foo.bar.baz()), as long as you get the object you want to spyOn as the first argument (foo.bar), you should be fine. 

If you have an object foo with a method "bar" and bar returns another object where you want to spy on the method "baz" (foo.bar().baz()), you'll want to return a spy from "bar". There's a couple different ways to do this -- jasmine provides the (poorly documented) method jasmine.createSpyObj that takes (IIRC, please check the source for the exact signature) a name and an array of method names that will be mapped as spies. IE, you could: 

var fakeObject = jasmine.createSpyObj("fakeObject", ['baz']);
spyOn(foo, "bar").andReturn(fakeObject);
expect(fakeObject.baz).not.toHaveBeenCalled();
foo.bar().baz();
expect(fakeObject.baz).toHaveBeenCalled(); 

Additionally, if you're trying to spy on a jquery chain, I would recommend spying on the $.fn you care about. IE, if you're doing something like: 

$(foo).text("some-text").show();

you can 

spyOn($.fn, "show")
var foo = $(".some-selector")
foo.text("some-text").show();
expect($.fn.show).toHaveBeenCalled();
expect($.fn.show.mostRecentCall.object).toEqual(foo);

Lastly, if you can *avoid* spying at all by simply triggering the behavior in question and then looking at either the DOM or the object to see that your behavior did the expected thing, you're probably best off going that route. Ideally, you're testing the results of your functions, not your implementation.

Hope that helps.

Rajan

apneadiving

unread,
Jun 29, 2011, 4:42:10 AM6/29/11
to Jasmine
Thanks for your answers, I'll try later but it seems to do the trick!

My goal is to stub googlemaps calls like google.maps.Point to avoid
external dependencies as advised here:
http://groups.google.com/group/jasmine-js/browse_thread/thread/5b1628e9dc5bc2d0
> On Tue, Jun 28, 2011 at 7:44 PM, Marc Chapman <marc.d.chap...@gmail.com>wrote:
>
> > I've done it by doing something to the effect of....
>
> > speyOn(foo.bar, "baz").andReturn("yo")
>
> > but in this case, bar needs to be an object as well as foo.
>
Reply all
Reply to author
Forward
0 new messages