38
Unit testing JavaScript using Mocha and Node.js

Unit testing JavaScript using Mocha and Node

Embed Size (px)

Citation preview

Page 1: Unit testing JavaScript using Mocha and Node

Unit testingJavaScript

using Mocha and Node.js

Page 2: Unit testing JavaScript using Mocha and Node

Josh MockSenior JavaScript architect at EmmaTwitter: Email:

@[email protected]

Page 3: Unit testing JavaScript using Mocha and Node

What is unit testing?Write code to test codeEnsures code works as expectedGranular, single-focus assertionsNot a substitute for QA

Page 4: Unit testing JavaScript using Mocha and Node

Why unit test?ConfidenceEasier refactoringLess regressionLess complexityTDD is fun!

Page 5: Unit testing JavaScript using Mocha and Node

What is Node.js?

Page 6: Unit testing JavaScript using Mocha and Node

Install Node.jsnode.js.org/download/

OS X (with Homebrew installed):brew install node

Page 8: Unit testing JavaScript using Mocha and Node

Install Mochanpm install -g mocha

Page 9: Unit testing JavaScript using Mocha and Node

Test some code!var Car = function () { this.make = "Honda"; this.model = "Civic";};

Page 10: Unit testing JavaScript using Mocha and Node

var assert = require("assert");

describe("Car", function () { describe("constructor", function () { it("should default the car to be a Honda Civic"); });

describe("makeAndModel", function () { it("should return a string containing the make and model"); });});

Page 11: Unit testing JavaScript using Mocha and Node

Run, tests, run

mocha path/to/test/file.js

Page 12: Unit testing JavaScript using Mocha and Node
Page 13: Unit testing JavaScript using Mocha and Node
Page 14: Unit testing JavaScript using Mocha and Node
Page 15: Unit testing JavaScript using Mocha and Node
Page 16: Unit testing JavaScript using Mocha and Node
Page 17: Unit testing JavaScript using Mocha and Node
Page 18: Unit testing JavaScript using Mocha and Node
Page 19: Unit testing JavaScript using Mocha and Node

How to write good testsTest results, not internalsOne focus per testTesting DOM changes is bold

Page 20: Unit testing JavaScript using Mocha and Node

How to write testable code

Page 21: Unit testing JavaScript using Mocha and Node

Simple, single-purpose functions// badvar numbers = { list: [1, 2, 3], add: function (newNum) { this.list.push(newNum); this.list.sort(); }};

// goodvar numbers = { list: [1, 2, 3], add: function (newNum) { this.list.push(newNum); }, sort: function () { this.list.sort(); }};

Page 22: Unit testing JavaScript using Mocha and Node

Avoid tight coupling of componentsvar numbers = { list: [1, 2, 3], add: function (newNum) { this.list.push(newNum); }};

// badvar math = { add: function () { var total = 0; for (var i = 0; i < numbers.list.length; i++) { total += numbers.list[i]; } return total; }, average: function () { return this.add() / numbers.list.length; }};

alert(math.average());

// goodvar math = { add: function (numList) { var total = 0; for (var i = 0; i < numList.length; i++) { total += numList[i]; } return total;

Page 23: Unit testing JavaScript using Mocha and Node

Separate business logic from UI(and avoid anonymous functions/callbacks)

var numbers = [2, 4, 1, 3, 5];

// bad$("a.sort-numbers").on("click", function (e) { e.preventDefault(); numbers.sort();});

// goodvar sortNumbers = function (e) { e && e.preventDefault && e.preventDefault(); numbers.sort();};$("a.sort-numbers").on("click", sortNumbers);

Page 24: Unit testing JavaScript using Mocha and Node

Advanced stuff!

Page 25: Unit testing JavaScript using Mocha and Node

Asynchronous tests

Page 26: Unit testing JavaScript using Mocha and Node

var asyncSort = function (numbers, callback) { setTimeout(function () { callback(numbers.sort()); }, 10);};

Page 27: Unit testing JavaScript using Mocha and Node

define("asyncSort", function () { it("should sort my numbers", function (done) { asyncSort([1, 3, 2], function (result) { assert.deepEqual(result, [1, 2, 3]); done(); }); });});

Page 28: Unit testing JavaScript using Mocha and Node

Sinon.jsnpm install -g sinon

Page 29: Unit testing JavaScript using Mocha and Node

Spiesvar sinon = require("sinon");

it("runs jQuery.ajax", function () { sinon.spy($, "ajax"); doAjaxCall(); assert($.ajax.calledOnce); $.ajax.restore();});

it("does some thing that takes forever", function () { someGlobal.slowFunction = sinon.spy(); callSlowFunction(); assert.equal(someGlobal.slowFunction.callCount, 1); assert(someGlobal.slowFunction.calledWith(1, "two", 3));});

Page 30: Unit testing JavaScript using Mocha and Node

Stubsvar sinon = require("sinon");

it("returns the age of a person with data stored in the database", function () { Database.get = sinon.stub().returns({ name: "Joe", age: 33 });

var getAge = function () { return Database.get("Joe").age; };

assert.equals(getAge(), 33);});

Page 31: Unit testing JavaScript using Mocha and Node

Mocksvar sinon = require("sinon");

it("should get the desired car from the database", function () { var mock = sinon.mock(Database);

mock .expects("getCar") .withExactArgs("Honda Civic") .once()

var car = new Car(); car.get("Honda Civic");

assert(mock.verify());});

Page 32: Unit testing JavaScript using Mocha and Node

Fake timersvar sinon = require("sinon");

it("should save after 30 seconds", function () { var clock = sinon.useFakeTimers();

sinon.spy($, "ajax");

delayedSave(); clock.tick(30001);

assert($.fn.ajax.called);

$.ajax.restore();});

Page 33: Unit testing JavaScript using Mocha and Node

jsdom and node-jqueryTest browser-dependent codeMake Node think it's a browserTest jQuery DOM manipulationsGo through all stages of grief getting it to work

Ponder using a browser-based framework instead

Page 34: Unit testing JavaScript using Mocha and Node

Installnpm install -g jsdom && npm install -g jquery

Page 35: Unit testing JavaScript using Mocha and Node

Set upGLOBAL.document = require("jsdom").jsdom();GLOBAL.window = document.createWindow();GLOBAL.$ = GLOBAL.jQuery = require("jquery").create(window);

Page 36: Unit testing JavaScript using Mocha and Node

Useit("should change div background color to blue", function () { $("body").html('<div id="mydiv"></div>'); $("#mydiv").css("background", "blue"); assert.equal($("#mydiv").css("background"), "blue");});

Page 37: Unit testing JavaScript using Mocha and Node

No headless browserNo GUI running in backgroundNo guarantees

Page 38: Unit testing JavaScript using Mocha and Node

THE ENDQuestions?

Twitter: Email:

@[email protected]

github.com/JoshMock/mocha-node-slides