2. Why test?
● Tests Reduce Bugs
● Tests are good documentation
● Tests allow safe refactoring
● Tests reduce the cost of change
● Testing forces you to think
● Tests gives confidence
● Tests reduce fear!
3. Unit Tests
● Isolate each part of the
program
● Show that the individual
parts are correct
Integration Tests
● Test the inter-operation
of multiple subsystems
● Test that “the nuts fit
the bolts”
4. What is NodeJS Unit Testing?
NodeJS unit testing refers to testing individual units or
components of a Node.js application using specialized
automation testing frameworks and libraries.
Popular NodeJS unit testing frameworks include Jest, Mocha,
and Chai.
5. chai vs jest vs mocha
Jest, Mocha and Chai have gained significant popularity
based on usage and monthly downloads, according to Github
and npmtrends,
https://npmtrends.com/chai-vs-jest-vs-mocha
7. Jest.js
setup config run
npm init -y
npm I –save-dev jest
Package.json
"scripts": {
"test": "jest"
}
"scripts": {
"test": "jest --coverage"
}
npm test
8. Jest.js - assertions
● expect( <this> ).toBe.<assertion>(that)
● Throws an Error if the assertion is false!
Examples:
● expect(sum(1, 2)).toBe(3)
● expect(subtract(1, 2)).toBe(-1)
● expect(cloneArray(array)).not.toBe(array)
● expect(cloneArray(array)).toEqual(array) // deep equality
9. Exercise: Write some tests
● Create a new node module (mkdir unit-test && npm init -y)
● Install devDeps (npm i --save-dev jest)
● Configure an “npm test” command
● Test these cases:
○ Sum Number -> returns a + b
○ Subtract Number -> returns a - b
○ Clone Array -> returns […array]
function isEven(n) { let
e = n % 2
if (Number.isNaN(e)) throw Error('Not a number!')
return !e
}
Gist
10.
11. Unit tests should come FIRST!
● Fast - 1K+ per second
● Isolated - Perform no I/O
● Repeatable - Run in any order, without intervention
● Self-validating - No external tool to evaluate results
● Timely - written before code
Source: http://agileinaflash.blogspot.co.il/2009/02/first.html
12. Tools of the trade
● Test Runner -> mocha.js
● Assertion Framework -> chai.js
● Stubbing/Mocking tools -> sinon.js
13. Testing Async Behavior
● Invoke the callback when your test is complete.
● By adding a callback (usually named done) to it(), Mocha will know that
it should wait for this function to be called to complete the test.
describe('Async behavior', function() {
before(function(done) {
somethingAsync(done)
})
it('should do ok', () => {})
})
14. Exercise: Test different calls to ipify.org
● ipify.org - has 3 formats, regular, json and jsonp
● Write a unit test which tests each type
● I use “axios” = request library with promises
const request = require('axios')
function getMyIP(fmt) {
fmt = typeof fmt == 'undefined' ? 'json' : fmt;
return request.get(`https://api.ipify.org?format=${fmt}`)
}
gist
15. Why are these tests bad?
● They test someone else’s code
● They make I/O!
16. Sinon.js - stubbing, mocking, spying
● sinon.stub(obj, ‘method’).returns(1)
What this does:
● Replaces obj.method() with function() { return 1 }
● Obj.method becomes a spy (gets special methods for
inspection)
● Gets a .reset() method which rolls counters back
● Gets a .restore() method which restores everything back
http://sinonjs.org/
17. Exercise: test our getMyIP’s different cases
● Stub axios.get
● Don’t forget to restore
● Test 3 cases:
○ No Input
○ JSON
○ JSONP
● Goals:
○ Test that Axios is called correctly
○ Don’t break the function’s signature
18. Bonus: pick your poison
● Testing Webservers
● Coverage reports with istanbul
● Syntactic sugar with sinon-as-promised, sinon-chai
● Integrating unit tests into CI/CD