Unit Testing Front End JavaScript
description
Transcript of Unit Testing Front End JavaScript
UNIT TESTING FRONT END JAVASCRIPT
YURI TAKHTEYEV
@QARAMAZOV@RANGLEIO
Why Bother with Unit Tests?
Why Bother with Unit Tests?
TDD Lite
Writing Testable Code
☛ Modular code
☛ AngularJS
services
☛ Other modules not entangled with DOM
Keeping Tests Simple
Common Tools
Runner: KarmaTask Automation: Gulp || GruntScorer: Mocha || JasmineAssertions: Chai || JasmineSpies: Sinon || Jasmin
+ CI tools (e.g. Magnum-CI)
http://yto.io/xunit
Installing the Example Code
# First installgit clone https://github.com/yuri/webu-unit.gitcd webu-unitnpm installsudo npm install -g gulpsudo npm install -g bowerbower install
# Now rungulp karma
☛ You’ll need to install git and node before
A Basic Testfunction isOdd(value) { return (value % 2 === 1);}
describe('isEven', function () { it('should handle positive ints', function () { if (isOdd(2)) { throw new Error('2 should be even'); } });});
☛ Let’s put this in “client/app/is-odd.test.js”
Chaidescribe('isEven', function () { it('should handle positive ints', function () { expect(isOdd(1)).to.be.true; expect(isOdd(2)).to.be.false; expect(isOdd(3)).to.be.true; });});
☛ More Chai at http://chaijs.com/api/bdd/
Extending Testsdescribe('isEven', function () { ... it('should handle negative ints', function () { expect(isOdd(-1)).to.be.true; });});
Extending Testsdescribe('isEven', function () { ... xit('should handle negative ints', function () { expect(isOdd(-1)).to.be.true; });});
Extending Testsdescribe('isEven', function () { ... it.only('should handle negative ints', function () { expect(isOdd(-1)).to.be.true; });});
Extending Testsdescribe('isEven', function () { ... it('should handle negative ints', function () { expect(isOdd(-1)).to.be.true; });});
function isOdd(value) { return (value % 2 === 1);}
Testing a Serviceangular.module('app.tasks', [ 'app.server'])
.factory('tasks', function(server) { var service = {};
service.getTasks = function () { return server.get('tasks'); };
return service;});
☛ Let’s put this in “client/app/tasks-service.js”
The Test, Take 1describe('tasks service', function () { beforeEach(module('app.tasks')); it('should get tasks', function() { var tasks = getService('tasks'); expect(tasks.getTasks()).to .not.be.undefined; });});
☛ Let’s put this in “client/app/tasks-service.test.js”
Error: [$injector:unpr] Unknown provider:serverProvider <- server <- tasks
☛ See “client/testing/test-utils.js” for implementation of getService().
Mocking Dependenciesvar data;beforeEach(module(function($provide){ $provide.service('server', function() { return { get: function() { return Q.when(data); } }; }); $provide.service('$q', function() { return Q; });}));
Chrome 37.0.2062 (Mac OS X 10.9.4): Executed 3 of 3 SUCCESS (0.046 secs / 0.027 secs)
Let’s Extend the Serviceservice.getMyTasks = function () { return server.getTasks() .then(function(taskArray) { return _.filter(taskArray, function(task) { return task.owner === user.userName; }); });};
☛ We’ll need to inject “user” into the service
Mocking the User$provide.service('user', function() { return { username: 'yuri' };});
☛ The mock can be very simple
An Async Test, Wrongit('should get user\'s tasks', function() { var tasks = getService('tasks'); data = [{ owner: 'bob', description: 'Mow the lawn' }, { owner: 'yuri', description: 'Save the world' }]; tasks.getMyTasks() .then(function(myTasks) { expect(myTasks.length).to.equal(1); });});
☛ Always check that “wrong” tests fail!
An Async Test, Rightit('should get user\'s tasks', function() { var tasks = getService('tasks'); data = [{ owner: 'bob', description: 'Mow the lawn' }, { owner: 'yuri', description: 'Save the world' }]; return tasks.getMyTasks() .then(function(myTasks) { expect(myTasks.length).to.equal(1); });});
Spies with Sinon$provide.service('server', function() { return { get: sinon.spy(function() { return Q.when(data); }) };});
var server = getService('server');return tasks.getMyTasks() .then(function(myTasks) { expect(myTasks.length).to.equal(1); server.get.should.have.been.calledOnce; });
Thank You.Contact: [email protected] http://yto.io @qaramazov
This presentation: http://yto.io/xunit
by dunechaser
Image Credits
by lincolnblues
by spenceyc
by creative_tools
by mycroyance
by angeljimenez
by snre