TDD witH

 Node.js

KOSTAS Bariotis

http://kostasbariotis.com

TEST

DRIVEN

Development

What's TDD

Kent Beck describes it as

  • Red

  • Green

  • Refactor

What about BDD?

Just put a B instead of a T

Setting up a Testsuite

describe('User', function() {
  describe('#save()', function() {
    it('should save without error', function(done) {

      var user = new User('Luna');
      user.save(function(err) {
        if (err) throw err;
        done();
      });

    });
  });
});

var assert = require('assert');

describe('Array', function() {
  describe('#indexOf()', function () {
    it('should return -1 when the value is not present', function () {

      assert.equal(-1, [1,2,3].indexOf(5));
      assert.equal(-1, [1,2,3].indexOf(0));

    });
  });
});

unit tests

The smallest unit of code that is testable.

Assertion+

should('abc').be.a.String();

a.should.be.eql(b);

this.obj.should.have.property('id').which.is.a.Number();
this.obj.should.have.property('path');

(10).should.be.within(0, 20);

(10).should.be.within(0, 20);

failedPromise().should.be.rejectedWith(Error, { message: 'boom' });

Unit tests

must be 

  • ISOLATED

  • FAST

Mocking 

/ Stubing

it("calls the original function", function () {
    var spy = sinon.spy();
    var proxy = once(spy);

    proxy();

    assert(spy.called);
});

it("returns the return value from the original function", function () {
    var stub = sinon.stub().returns(42);
    var proxy = once(stub);

    assert.equals(proxy(), 42);
});

it("returns the return value from the original function", function () {
    var myAPI = { method: function () {} };
    var mock = sinon.mock(myAPI);
    mock.expects("method").once().returns(42);

    var proxy = once(myAPI.method);

    assert.equals(proxy(), 42);
    mock.verify();
});

FUNCTIONAL 

Testing

MULTIPLE UNITS WORKING TOGETHER

it("saves a User", function () {

    var userModel = new User({ 
        first_name: 'Kostas', 
        last_name: 'Bariotis' 
    })

    userModel
        .save()
        .then(function(model){

            db.collection('users')
                .findOne({ last_name: 'Bariotis'})
                .then(function(model) {
                    assert(model.first_name).equals('Kostas');
                    assert(model.last_name).equals('Bariotis');
                })

        })
});
var request = require('supertest');

describe('GET /user', function(){
  it('respond with json', function(done){

    request('http://localhost:3000')
      .get('/user')
      .set('Accept', 'application/json')
      .expect('Content-Type', /json/)
      .expect(200, done);

  })
})
var nock = require('nock');

var couchdb = nock('http://localhost:5984/')
                .get('/users/1')
                .reply(200, {
                  _id: '123ABC',
                  _rev: '946B7D1C',
                  username: 'kbariotis',
                  email: 'kbariotis@goodvid.io'
                 });

END TO END TESTing

var Browser = require('zombie');

describe('User visits signup page', function() {

  var browser = new Browser();

  before(function(done) {
    browser.visit('/signup', done);
  });

  describe('submits form', function() {

    before(function(done) {
      browser
        .fill('email',    'zombie@underworld.dead')
        .fill('password', 'eat-the-living')
        .pressButton('Sign Me Up!', done);
    });

    it('should be successful', function() {
      browser.assert.success();
    });

    it('should see welcome page', function() {
      browser.assert.text('title', 'Welcome To Brains Depot');
    });
  });
});

THANKS

If you liked my presentation, surely you'll like my tweets.

Check'em out at @kbariotis

TDD with Node.js

By Kostas Bariotis

TDD with Node.js

An introduction to TDD and various techniques to integrate it into your Nodejs Application.

  • 3,132