Skip to content

Instantly share code, notes, and snippets.

@james-gardner
Last active August 29, 2015 14:00
Show Gist options
  • Save james-gardner/11405316 to your computer and use it in GitHub Desktop.
Save james-gardner/11405316 to your computer and use it in GitHub Desktop.
Testing Backbone with Jasmine 2 and Sinon (RequireJS)
define(['backbone', 'dummy/models/DummyModel'], function (Backbone, DummyModel) {
var Collection = Backbone.Collection.extend({
url : '/dummies',
model : DummyModel
});
return Collection;
});
describe('dummy collection', function () {
var collection, items;
beforeEach(function (done) {
items = [
{ id : 1, title : 'Dummy Item 1' },
{ id : 2, title : 'Dummy Item 2' },
{ id : 3, title : 'Dummy Item 3' },
{ id : 4, title : 'Dummy Item 4' },
{ id : 5, title : 'Dummy Item 5' }
];
require(['dummy/collections/DummyCollection'], function (DummyCollection) {
collection = new DummyCollection(items);
done();
});
});
it('should parse dummy items into dummy model instances', function () {
expect(collection.every(function (m) {
return(m.name === 'DummyModel');
})).toBe(true);
});
});
define(['backbone'], function (Backbone) {
var View = Backbone.View.extend({
tagName : 'p',
initialize : function () {
this.listenTo(this.model, 'change', this.onChange);
},
onChange : function (model) {
if(_.has(model.changed, 'title')) {
this.$el.text(model.get('title'));
}
},
render : function () {
this.$el.text(this.model.get('title'));
return this.$el;
}
});
return View;
});
describe('dummy item view', function () {
var view;
beforeEach(function (done) {
require(['dummy/views/DummyItemView', 'dummy/models/DummyModel'], function (DummyItemView, DummyModel) {
spyOn(DummyItemView.prototype, 'onChange').and.callThrough();
view = new DummyItemView({
model : new DummyModel({
title : 'Dummy Item 1'
})
});
done();
});
});
it('should reflect changes made to a dummy model', function () {
var title = 'A changed dummy title.';
view.model.set('title', title);
expect(view.$el.text()).toEqual(title);
})
});
define(['backbone'], function (Backbone) {
var Model = Backbone.Model.extend({
name : 'DummyModel'
});
return Model;
});
define(['backbone', 'dummy/views/DummyItemView', 'backbone_babysitter'], function (Backbone, DummyItemView) {
var View = Backbone.View.extend({
initialize : function () {
this.listenTo(this.collection, 'add', this.addOne);
this.listenTo(this.collection, 'remove', this.removeOne);
this.container = new Backbone.ChildViewContainer();
},
addAll : function () {
},
addOne : function (model) {
var view = new DummyItemView({
model : model
});
this.container.add(view);
this.$el.append(view.render());
},
removeOne : function (model) {
var view = this.container.findByModelCid(model.cid);
this.container.remove(view);
view.remove();
},
render : function () {
return this.$el;
}
});
return View;
});
describe('dummy view', function () {
var el, view, items, server = sinon.fakeServer.create();
beforeEach(function (done) {
items = [
{ id : 1, title : 'Dummy Item 1' },
{ id : 2, title : 'Dummy Item 2' },
{ id : 3, title : 'Dummy Item 3' },
{ id : 4, title : 'Dummy Item 4' },
{ id : 5, title : 'Dummy Item 5' }
];
server.respondWith('GET', '/dummies', [ 200, { "Content-Type": "application/json" }, JSON.stringify(items)]);
require(['dummy/views/DummyView', 'dummy/collections/DummyCollection'], function (DummyView, DummyCollection) {
spyOn(DummyView.prototype, 'addOne').and.callThrough();
spyOn(DummyView.prototype, 'removeOne').and.callThrough();
view = new DummyView({
collection : new DummyCollection()
});
done();
});
});
it('should serve as a working example', function () {
expect(true).toBe(true);
});
it('should retrieve a complete list of dummy items', function () {
view.collection.fetch().done(function () {
expect(view.container.length).toEqual(items.length);
});
server.respond();
});
it('should show new items immediately', function () {
view.collection.add({
title : 'Dummy Item 6'
});
// To demonstrate spies. Not really a valid test.
expect(view.addOne.calls.count()).toEqual(1);
});
it('should react to models being deleted', function () {
view.collection.set(items);
var cid = view.collection.first().cid;
view.collection.remove(cid);
expect(view.container.findByModelCid(cid)).toBeUndefined();
});
});
require.config({
paths: {
'jasmine' : 'lib/jasmine/jasmine',
'jasmine-html' : 'lib/jasmine/jasmine-html',
'boot' : 'lib/jasmine/boot-amd',
'spec' : 'spec/',
'backbone' : 'lib/backbone/backbone-1.1.2',
'underscore' : 'lib/lodash/lodash-2.4.1',
'jquery' : 'lib/jquery/jquery-1.11.0',
'sinon' : 'lib/sinon/sinon-1.9.1',
'dummy' : 'src/dummy'
},
shim: {
'jasmine': {
exports: 'window.jasmineRequire'
},
'jasmine-html': {
deps: ['jasmine'],
exports: 'window.jasmineRequire'
},
'boot': {
deps: ['jasmine', 'jasmine-html'],
exports: 'window.jasmineRequire'
},
'backbone' : {
deps : ['underscore', 'jquery'],
exports :'Backbone'
}
}
});
require(['boot', 'sinon', 'backbone'], function() {
var specs = [
'spec/collections/DummyCollectionSpec.js',
'spec/views/dummy/DummyViewSpec.js',
'spec/views/dummy/DummyItemViewSpec.js',
];
require(specs, function () {
window.executeTests();
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment