I am writing a Backbone.js app using Require.js and Backbone.Marionette and testing it using Mocha with Chai, Sinon, and Sinon-Chai. I’ve been generally using Jarrod Overson’s Backbone Marionette with Require.JS TODO sample as a reference for application structure and Jim Newbery’s posts on testing Backbone apps as a reference for unit testing.
My problem is trying to test adding a Marionette ItemView to a Marionette Application object. I figured the best way to test that the ItemView is added is watch for its render() method to be called. Since Marionette provides a default render() implementation, I thought it best to just use a Sinon spy for the onRender() callback.
I used Squire.JS to return a stub class for my ItemView as shown below:
define(['Squire', 'backbone.marionette'], function(Squire, Marionette) {
describe('App', function() {
var testContext;
beforeEach(function(done) {
testContext = {};
testContext.injector = new Squire();
testContext.renderSpy = sinon.spy();
testContext.injector.mock('app/views/Header', function() {
var stub_template_html = "<div></div>";
var HeaderStub = Marionette.ItemView.extend({
template: function(serialized_model) {
return _.template(stub_template_html);
}
});
return HeaderStub;
});
testContext.injector.require(['app/app'], function(app) {
testContext.app = app;
done();
});
});
it ('Should add a Header view to the \'header\' region', function() {
testContext.app.start();
expect(testContext.renderSpy).to.be.called();
});
When I run Mocha via Chrome, I get the error I expect: “expected spy to have been called at least once, but it was never called.” However, if I specify the Sinon spy function as the onRender() callback, as shown below
var HeaderStub = Marionette.ItemView.extend({
// ...
onRender: testContext.renderSpy
});
I get an error stating that the called() method is not a function.
Is there a way to specify a Sinon spy function as a method in a class definition? Alternatively, is there a better way to test this code? I’m fairly new to JavaScript, so this may be a more general problem rather than a Sinon-specific problem.
Any help is appreciated.
I’m not sure what assertion library you are using, but to check if a function you spy on with sinon was called, you have to check the
calledproperty of the spy. See http://sinonjs.org/docs/#spiesSo your assertion should look like this: