Craftsy
@bkonkle
Unit testing helps you write better code!
Tests that describe how a user interacts with your application and check the results based on what the user should see. All of the components of your app are tested together, fully integrated.
Tests that evaluate the output of a small piece of functionality given a set of inputs. The code is as isolated from other functionality as possible, with external calls mocked out so that they don't affect the test.
A test runner. It provides:
/* global describe, it, beforeEach */
'use strict';
var SonicScrewdriver = require('./src/SonicScrewdriver');
describe('SonicScrewdriver', function() {
describe('(constructor)', function() {
it('Establishes a mental connection with the user', function() {
// ** Test code goes here **
});
// ** More tests go here **
});
describe('#handleCommand()', function() {
beforeEach(function() {
// ** Setup that is run before each test in this group **
});
it('Responds to mental commands from the user', function() {
// ** Mose test code goes here **
});
// ** More tests go here **
});
});
An assertion library. It provides:
// Assert style
assert.equal(whoAmI, 'Groot', 'I am Groot');
assert.isTrue(teaServed, 'the tea has been served');
assert.instanceOf(chai, Tea, 'chai is an instance of tea');
// Expect style
expect(whoAmI).to.equal('Groot');
expect(teaServed).to.be.true;
expect(chai)to.be.an.instanceOf(Tea);
// Should style
whoAmI.should.equal('Groot');
teaServed.should.be.true;
chai.should.be.an.instanceOf(Tea);
Mocking library. Provides:
Mocks are not generally needed.
It's often clearer to use Chai assertions with the spy tracking.
'use strict';
var chai = require('chai');
var sinon = require('sinon');
var SonicScrewdriver = require('./src/SonicScrewdriver');
var expect = chai.expect;
describe('SonicScrewdriver', function() {
describe('(constructor)', function() {
var testConnection = sinon.spy();
var origGetConnection;
before(function() {
// Save the original getConnection functionality
origGetConnection = SonicScrewdriver.getConnection;
});
beforeEach(function() {
// Set up a fresh stub for the mental connection code
SonicScrewdriver.getConnection = sinon.stub().returns(testConnection);
});
after(function() {
// Restore the original getConnection functionality
SonicScrewdriver.getConnection = origGetConnection;
});
it('Establishes a mental connection with the user', function() {
var testScrewdriver = new SonicScrewdriver();
expect(SonicScrewdriver.getConnection).to.have.been.called;
expect(testScrewdriver._connection).to.equal(testConnection);
});
});
var xhr, requests;
beforeEach(function() {
// Use Sinon to intercept Ajax requests
xhr = sinon.useFakeXMLHttpRequest();
requests = [];
xhr.onCreate = function (xhr) {
requests.push(xhr);
};
});
after(function() {
xhr.restore();
});
// One Ajax request should be sent
expect(requests).to.have.length(1);
var request = requests[0];
// It should be hitting the screwdriver endpoint
expect(request.url).to.equal('/api/v1/screwdriver');
// It should be a POST request
expect(request.method).to.equal('POST');
// The body should contain a screwdriver id
expect(request.requestBody).to.contain('id=' + testScrewdriver.id);
var request = requests[0];
var status = 200;
var headers = {'Content-Type': 'application/json'}
var body = JSON.stringify({'success': true});
request.respond(status, headers, body);