My example of spying on a method is failing with "Expected spy handle_click to have been called." when it should pass. However, I am getting the console log "Foo handle_click called!", so I know it's being called.
Foo.js
function Foo() {
this.$btn = $('<a href="#">Foo</a>');
this.$btn.on('click', this.handle_click);
};
Foo.prototype.handle_click = function(evt) {
evt.preventDefault();
console.log('Foo handle_click called!');
};
Foo_spec.js:
it('should be called when trigger is clicked', function() {
var foo = new Foo();
spyOn( foo, 'handle_click' ).andCallThrough();
foo.$btn.click();
expect( foo.handle_click ).toHaveBeenCalled();
});
I am using jasmine-1.2.0, jasmin-html and jasmine-jquery, but not jasmine-sinon; at-least I don't think it's bundled in there. Any help is much appreciated!
Update This was answered below. However, I wanted to document the solution in the case of a jQuery Plugin:
Foo.js:
function Foo() { ... }
Foo.prototype.handle_click = function(evt) { ... }
$.fn.foo = function(options) {
return new Foo(this, options || {});
};
$.fn.foo.prototype = Foo.prototype;
Foo_spec.js:
it('should be called when clicked', function() {
spyOn( $.fn.foo.prototype, 'handle_click');
var plugin = $('#selector-for-plugin').foo();
plugin.$btn.click();
expect( plugin.handle_click ).toHaveBeenCalled();
});
There are two ways to create a spy in Jasmine: spyOn() can only be used when the method already exists on the object, whereas jasmine. createSpy() will return a brand new function: //spyOn(object, methodName) where object. method() is a function spyOn(obj, 'myMethod') //jasmine.
toHaveBeenCalled() Matcher The toHaveBeenCalled() matcher verifies whether the spied method has been called or not. It returns true if the spy was called.
The problem is that you bind the handle_click
function in the constructor. So when you create a new instance a reference to the function is binded to the event. After that you replace the foo.handle_click
with a spy. But this will not effect the function that was binded to the event as this is still your original function. You have to spy on the Foo.prototype.handle_click
function before you create the instance, so the spied function can be bound to the event.
it('should be called when trigger is clicked', function() {
spyOn( Foo.prototype, 'handle_click' );
var foo = new Foo();
foo.$btn.click();
expect( foo.handle_click ).toHaveBeenCalled();
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With