Problem
Its my first attempt to unit-test in Js. Not yet TDD.
What I can change?
EventsPersistancyService.js:
var Q = require('q');
var EventsPersistancyService = {
accept: function acceptService(msg) {
var worker_id = WorkerCacheService.get('some login');
var app_category = AppCategoryService.get('some');
var p = Q.all([worker_id, app_category]).then(function () {
var content = msg.content.toString();
content = JSON.parse(content);
return Event.create(content);
});
return p;
}
}
module.exports = EventsPersistancyService;
Unit tests:
"use strict";
var assert = require('assert');
var chai = require('chai');
var expect = chai.expect;
var chaiAsPromised = require('chai-as-promised');
var sinonChai = require("sinon-chai");
chai.use(chaiAsPromised);
chai.use(sinonChai);
var sinon = require('sinon');
var Q = require('q');
var TPL = {
};
describe('EventsPersistancyService', function () {
describe('#accept', function () {
var s1, s2, s3, s4;
var message = {
fields: null,
properties: null,
content: new Buffer(JSON.stringify(TPL))
};
beforeEach(function () {
s1 = sinon.stub(WorkerCacheService, 'get').returns(Q.resolve(""));
s2 = sinon.stub(AppCategoryService, 'get').returns(Q.resolve(""));
s3 = sinon.stub(Event, 'create').returns(Q.resolve(1));
});
afterEach(function () {
sinon.sandbox.restore();
s1.restore();
s2.restore();
s3.restore();
});
it('should return error when accept param is null', function () {
var res = EventsPersistancyService.accept(null);
return expect(res).to.be.rejected;
});
it('should return resolve promise on non error situation', function () {
var res = EventsPersistancyService.accept(message);
return expect(res).to.be.not.rejected;
});
it('should call WorkerCacheService to get worker_id', function () {
EventsPersistancyService.accept(message);
return expect(s1).to.have.been.calledOnce;
});
it('should call AppCategoryService to get app_category', function () {
EventsPersistancyService.accept(message).then();
return expect(s2).to.have.been.calledOnce;
});
it('should call Event.create when all if ok', function () {
EventsPersistancyService.accept(message).then(function () {
expect(s4).to.have.been.calledOnce;
}, function () {
expect(s4).to.have.been.calledOnce;
});
});
it('should reject when Event.create reject', function () {
s3.restore();
s3 = sinon.stub(Event, 'create').returns(Q.reject(1));
var p = EventsPersistancyService.accept(message);
return expect(p).to.be.rejected;
});
it('should reject when Event.create throw', function () {
var p = EventsPersistancyService.accept({});
return expect(p).to.be.rejected;
});
it('should reject when WorkerCacheService.get fails', function () {
s1.restore();
s1 = sinon.stub(WorkerCacheService, 'get').returns(Q.reject(''));
var p = EventsPersistancyService.accept(message);
return expect(p).to.be.rejected;
});
it('should reject when AppCategoryService.get fails', function () {
s2.restore();
s2 = sinon.stub(AppCategoryService, 'get').returns(Q.reject(''));
var p = EventsPersistancyService.accept(message);
expect(p).to.be.rejected;
});
});
});
Solution
Use sinon-promises
to simplify this:
'use strict';
const chai = require('chai');
const sinon = require('sinon');
const sinonChai = require('sinon-chai');
const chaiAsPromised = require('chai-as-promised');
const sinonStubPromise = require('./..');
sinonStubPromise(sinon);
chai.use(chaiAsPromised);
chai.use(sinonChai);
const expect = chai.expect;
let stub;
describe('stubbing promises', () => {
beforeEach(() => {
stub = sinon.stub();
});
it('should not throw an error when invoked', () => {
stub.returnsPromise();
});
it('should allow defining a resolve value', () => {
stub.returnsPromise();
stub.resolves(1);
return expect(stub()).to.eventually.equal(1);
});
it('should allow defining a reject value', () => {
stub.returnsPromise();
const err = new Error();
stub.rejects(err);
return expect(stub()).to.eventually.be.rejectedWith(err);
});
it('should allow overwriting a resolves with a reject', () => {
stub.returnsPromise();
const err = new Error();
stub.resolves(1);
stub.rejects(err);
return expect(stub()).to.eventually.be.rejectedWith(err);
});
it('should allow overwriting a reject with a resolves', () => {
stub.returnsPromise();
const err = new Error();
stub.rejects(err);
stub.resolves(1);
return expect(stub()).to.eventually.equal(1);
});
it('should be last-write-wins', () => {
stub.returnsPromise();
stub.resolves(1);
stub.resolves(2);
stub.resolves(3);
return expect(stub()).to.eventually.equal(3);
});
});
References