Expected spy to have been called with [ ... ] but was called with [ [ ... ] ] Why?

18,158 views
Skip to first unread message

Tim

unread,
Apr 20, 2011, 4:09:45 PM4/20/11
to Jasmine
This is my first day with Jasmine, so apologies if this I have missed
something from the docs.

Running the code and spec below using Jasmine version 1.0.2, the spec
for app.repeat fails with:

Expected spy to have been called with [ Function, 100 ] but was called
with [ [ Function, 100 ] ].

Can anyone explain this to me please? Is this an edge-case bug or Is
there a better way to express the spec.

I am intentionally spying on window.setInterval (native) and LibObj
(third party code).

// LibObj.js
var LibObj = {};

LibObj.fn = function () {
// do something with arguments
};

function Bar(arg) {
// do something with arg
}

// App.js
function App() {}

App.prototype.once = function(a) {
return LibObj.fn("string", Bar(a));
};

App.prototype.repeat = function(a, b) {
return setInterval(function() {
LibObj.fn("string", Bar(a));
}, b);
};

// AppSpec.js
describe("App", function() {
var app, callback = function() {};

beforeEach(function() {
app = new App();
});

describe("once(callback)", function() {
it("should call LibObj.fn with 'string' and Bar(callback)",
function() {
spyOn(LibObj, 'fn');
app.once(callback);

expect(LibObj.fn).toHaveBeenCalledWith("string", Bar(callback));
});
});

describe("repeat(callback, 100)", function() {
it("should call LibObj.fn with 'string' and Bar(callback) every
100 milliseconds", function() {
spyOn(window, 'setInterval');
app.repeat(callback, 100);

expect(window.setInterval).toHaveBeenCalledWith(function()
{ LibObj.fn("string", Bar(callback)); }, 100);
});
});

});

Brian Murrell

unread,
Apr 21, 2011, 1:46:01 PM4/21/11
to Jasmine
Hi Tim,

What environment are you running (e.g. what browser, etc?).

I found some crazy results such as this when running under QT Webkit
(see my inquiry http://bit.ly/hgYxf2 ). in my case, this evaluation
reported an incorrect state about 25% of the time (if i just continued
to reload the same test, infrequently, it would pass).

In my case, I have an embedded qtwebkit... the problem (obvious lie
"expected 'bar' to equal 'bar'") seemed to be in qtwebkit 4.6.1. i
rebuilt my environment with qtwebkit 4.7.1 and the problem went
away... so there was no concrete, explicable solution.

but what this led me to believe was that there was a threading problem
where part of the jasmine core was not loaded properly at evaluation
time, espeically since it was intermittent... i don't know... but i
think it will be useful for you to post your environment.

brian

Frank Schwieterman

unread,
Apr 21, 2011, 1:46:22 PM4/21/11
to jasmi...@googlegroups.com
The problem is the Function parameter is not equal to what you
wanted to match, though it may have the same content. Consider that
(function() { }) != (function() { }) evaluates to true.

What you can do is

expect(window.setInterval).toHaveBeenCalledWith(jasmine.any("function"),
100);

To verify some function was passed in, though you'll want another
test to verify that function does what it should.

I prefer using Jasmine.clock for testing timers, as then I'm testing
the intended results of the callback rather then the mechanics of how
the timer is set up.

> --
> 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.
>
>

Alex Chaffee

unread,
Apr 21, 2011, 2:27:14 PM4/21/11
to jasmi...@googlegroups.com
On Thu, Apr 21, 2011 at 10:46 AM, Frank Schwieterman <fsch...@gmail.com> wrote:
>  I prefer using Jasmine.clock for testing timers, as then I'm testing
> the intended results of the callback rather then the mechanics of how
> the timer is set up.

And see http://groups.google.com/group/jasmine-js/browse_thread/thread/dbdc5ad1c1514322/a20949232ace1ae6
for more details on Jasmine's Mock Clock.

--
Alex Chaffee - al...@stinky.com - http://alexch.github.com
Stalk me: http://friendfeed.com/alexch | http://twitter.com/alexch |
http://alexch.tumblr.com

Tim

unread,
Apr 21, 2011, 3:47:34 PM4/21/11
to Jasmine
@All, Thanks for the feedback.

Great to see a helpful and thriving community behind Jasmine! I have
some prior experience with RSpec and starting to use Jasmine has been
really fun and productive.

@Brian, I was running in Firefox on Mac OSX 10.6, though in this case
I suspect it is not relevant (my example failed every time).

@Frank, That's what I suspected (about the contents differing,
although I found the error message to be a little misleading).

@Frank and @Alex. Once I had some sleep, I went back to problem and
found the thread on testing timers. As you both suggested: I've solved
it by using jasmine.Clock and removing the spy on window.setInterval.
I now do the same expectation on LibObj.fn as in the "once" spec after
ticking the jasmine.Clock on past the specified interval.

Solution here for others following in my footsteps:

describe("repeat(callback, 100)", function() {
it("should call LibObj.fn with 'string' and Bar(callback) every 100
milliseconds", function() {
jasmine.Clock.useMock();
app.repeat(callback, 100);

jasmine.Clock.tick(100);
expect(LibObj.fn).toHaveBeenCalledWith("string", Bar(callback));

jasmine.Clock.tick(100);

Rajan Agaskar

unread,
Apr 22, 2011, 7:50:16 AM4/22/11
to jasmi...@googlegroups.com
I should note that there's some buggy display with the haveBeenCalledWith matcher -- the results are wrapped in an additional array because the "actual" in this case is an array of the arguments for each call you've made to the spy. IE, had you made two calls, you might have seen something like: 

Expected spy to have been called with [ Function, 100 ] but was called with [ [ Function, 100 ], [Function, 200] ].

If you want to file an issue against this we can try to prioritize a better handling of this error message.

Thanks!

Rajan


Davis Frank

unread,
Apr 22, 2011, 11:55:23 AM4/22/11
to jasmi...@googlegroups.com
Actually, that one's in the backlog already. There's been some debate about how best to report arguments to spy calls.
--dwf
Reply all
Reply to author
Forward
0 new messages