stub-promise-function
Advanced tools
Comparing version 2.0.3 to 2.1.0
@@ -1,7 +0,16 @@ | ||
var stubPromiseFunction = require('stub-promise-function'); | ||
var expect = require('expectations'); | ||
var sinon = require('sinon'); | ||
var stubPromiseFunction = require('./'); | ||
var http = { | ||
get: function() { | ||
// simulates a http module with a GET function | ||
} | ||
}; | ||
var someFunction = function() {}; | ||
// code under test | ||
function getUsers() { | ||
http.get('/users.html').then(function(response) { | ||
console.log(response.data); | ||
someFunction(response); | ||
}); | ||
@@ -14,4 +23,4 @@ }; | ||
beforeEach(function() { | ||
someFunction = sinon.spy(); | ||
http.get = stubPromiseFunction(); | ||
sinon.spy(console, 'log'); | ||
}); | ||
@@ -28,6 +37,8 @@ | ||
describe('when getUsers resolves', function() { | ||
describe('when http.get resolves', function() { | ||
var response; | ||
beforeEach(function() { | ||
var response = { | ||
response = { | ||
data: 'foo' | ||
@@ -40,4 +51,5 @@ } | ||
it('logs response.data to console', function() { | ||
expect(console.log.getCall(0).args[0]).toBe('foo'); | ||
it('invokes someFunction', function() { | ||
expect(someFunction.called).toBe(true); | ||
expect(someFunction.getCall(0).args[0]).toBe(response); | ||
}); | ||
@@ -50,1 +62,44 @@ | ||
}); | ||
describe('multiple calls', function() { | ||
beforeEach(function() { | ||
someFunction = sinon.spy(); | ||
http.get = stubPromiseFunction(); | ||
}); | ||
beforeEach(function() { | ||
getUsers(); | ||
getUsers(); | ||
}); | ||
describe('resolving multiple calls', function() { | ||
var response1; | ||
var response2; | ||
beforeEach(function() { | ||
response1 = { | ||
data: 'Jon' | ||
}; | ||
http.get.resolve(response1) | ||
response2 = { | ||
data: 'Ana' | ||
}; | ||
http.get.resolve(response2) | ||
}); | ||
describe('when resolved', function() { | ||
it('it has resolved both http get calls', function() { | ||
expect(someFunction.callCount).toBe(2); | ||
expect(someFunction.getCall(0).args[0]).toBe(response1); | ||
expect(someFunction.getCall(1).args[0]).toBe(response2); | ||
}); | ||
}); | ||
}); | ||
}); |
26
index.js
@@ -6,15 +6,27 @@ 'use strict'; | ||
module.exports = function() { | ||
var deferred = Q.defer(); | ||
var calls = []; | ||
var func = sinon.stub().returns(deferred.promise); | ||
var func = function() { | ||
var deferred = Q.defer(); | ||
calls.push(deferred); | ||
return deferred.promise; | ||
}; | ||
func.resolve = function(value) { | ||
deferred.resolve(value); | ||
} | ||
if (calls.length > 0) { | ||
calls.shift().resolve(value); | ||
} else { | ||
throw 'Resolve cannot be called when there are no more promises to resolve/reject'; | ||
} | ||
}; | ||
func.reject = function(reason) { | ||
deferred.reject(reason); | ||
} | ||
if (calls.length > 0) { | ||
calls.shift().reject(reason); | ||
} else { | ||
throw 'Reject cannot be called when there are no more promises to resolve/reject'; | ||
} | ||
}; | ||
return func; | ||
return sinon.spy(func); | ||
} |
{ | ||
"name": "stub-promise-function", | ||
"version": "2.0.3", | ||
"version": "2.1.0", | ||
"description": "A test utility that lets you stub and control promises for testing purposes", | ||
@@ -5,0 +5,0 @@ "repository": "https://github.com/jonbern/stub-promise-function.git", |
141
README.md
# stub-promise-function | ||
A tiny test utility that lets you stub functions that return promises and manage the control flow of the returned promise. | ||
A test utility for stubbing functions that return promises. The promises' control flow can be controlled on the outside of the code under test, in in your test suite, by calling the exposed resolve() and reject() functions. | ||
@@ -14,7 +14,9 @@ ## npm package | ||
var stubPromiseFunction = require('stub-promise-function'); | ||
``` | ||
```javascript | ||
// code under test | ||
function getUsers() { | ||
http.get('/users.html').then(function(response) { | ||
console.log(response.data); | ||
someFunction(response); | ||
}); | ||
@@ -27,4 +29,4 @@ }; | ||
beforeEach(function() { | ||
someFunction = sinon.spy(); | ||
http.get = stubPromiseFunction(); | ||
sinon.spy(console, 'log'); | ||
}); | ||
@@ -41,6 +43,8 @@ | ||
describe('when getUsers resolves', function() { | ||
describe('when http.get resolves', function() { | ||
var response; | ||
beforeEach(function() { | ||
var response = { | ||
response = { | ||
data: 'foo' | ||
@@ -53,4 +57,5 @@ } | ||
it('logs response.data to console', function() { | ||
expect(console.log.getCall(0).args[0]).toBe('foo'); | ||
it('invokes someFunction', function() { | ||
expect(someFunction.called).toBe(true); | ||
expect(someFunction.getCall(0).args[0]).toBe(response); | ||
}); | ||
@@ -63,118 +68,38 @@ | ||
}); | ||
``` | ||
## Documentation | ||
describe('multiple calls', function() { | ||
```javascript | ||
describe('#stubPromiseFunction()', function() { | ||
var http; | ||
var promise; | ||
beforeEach(function() { | ||
http = { | ||
get: stubPromiseFunction() | ||
}; | ||
someFunction = sinon.spy(); | ||
http.get = stubPromiseFunction(); | ||
}); | ||
it('returns a function which returns a promise', function() { | ||
promise = http.get(); | ||
expect(promise.then).toBeDefined(); | ||
expect(typeof promise.then === "function"); | ||
beforeEach(function() { | ||
getUsers(); | ||
getUsers(); | ||
}); | ||
describe('returned promise', function() { | ||
describe('resolving multiple calls', function() { | ||
beforeEach(function() { | ||
promise = http.get('http://whatever'); | ||
}); | ||
var response1; | ||
var response2; | ||
it('has a #resolve function', function() { | ||
expect(http.get.resolve).toBeDefined(); | ||
expect(typeof promise.resolve === "function"); | ||
}); | ||
it('has a #reject function', function() { | ||
expect(http.get.reject).toBeDefined(); | ||
expect(typeof promise.reject === "function"); | ||
}); | ||
describe('#resolve()', function() { | ||
it('resolves the promise', function(done) { | ||
var expectedResponse = { data: 42 }; | ||
promise.then(function(response) { | ||
expect(response).toEqual(expectedResponse); | ||
done(); | ||
}); | ||
http.get.resolve(expectedResponse); | ||
}); | ||
}); | ||
describe('#reject()', function() { | ||
it('rejects the promise', function(done) { | ||
var expectedReason = 'some reason why'; | ||
promise.catch(function(error) { | ||
expect(error).toEqual(expectedReason); | ||
done(); | ||
}); | ||
http.get.reject(expectedReason); | ||
}); | ||
}); | ||
}); | ||
describe('spy functionality (using sinon.spy internally)', function() { | ||
beforeEach(function simulateApi() { | ||
http.get('http://whatever'); | ||
}); | ||
it('can be used together with test spies', function() { | ||
expect(http.get.called).toBe(true); | ||
expect(http.get.getCall(0).args[0]).toBe('http://whatever'); | ||
}); | ||
}); | ||
describe('multiple invocation by re-instantiation', function() { | ||
var http; | ||
var promise; | ||
beforeEach(function() { | ||
http = { | ||
get: stubPromiseFunction() | ||
response1 = { | ||
data: 'Jon' | ||
}; | ||
http.get.resolve(response1) | ||
promise = http.get('http://whatever'); | ||
promise.then(function(response) { | ||
expect(response.data).toEqual(42); | ||
}) | ||
http.get.resolve({ | ||
data: 42 | ||
}); | ||
response2 = { | ||
data: 'Ana' | ||
}; | ||
http.get.resolve(response2) | ||
}); | ||
it('can be reinstantiated and then resolved', function() { | ||
http.get = stubPromiseFunction(); | ||
describe('when resolved', function() { | ||
promise = http.get('http://another'); | ||
promise.then(function(response) { | ||
expect(response.data).toEqual(84); | ||
}) | ||
http.get.resolve({ | ||
data: 82 | ||
it('it has resolved both http get calls', function() { | ||
expect(someFunction.callCount).toBe(2); | ||
expect(someFunction.getCall(0).args[0]).toBe(response1); | ||
expect(someFunction.getCall(1).args[0]).toBe(response2); | ||
}); | ||
@@ -181,0 +106,0 @@ |
166
tests.js
@@ -49,2 +49,3 @@ 'use strict'; | ||
//console.log('http.get.resolve: ', http.get.resolve); | ||
http.get.resolve(expectedResponse); | ||
@@ -72,3 +73,3 @@ }); | ||
describe('spy functionality (using sinon.spy internally)', function() { | ||
describe('spy functionality', function() { | ||
@@ -79,3 +80,3 @@ beforeEach(function simulateApi() { | ||
it('can be used together with test spies', function() { | ||
it('exposes sinon.spy() API', function() { | ||
expect(http.get.called).toBe(true); | ||
@@ -87,2 +88,163 @@ expect(http.get.getCall(0).args[0]).toBe('http://whatever'); | ||
describe('multiple calls', function() { | ||
var spy1; | ||
var spy2; | ||
var spy3; | ||
var rejectSpy1; | ||
var rejectSpy2; | ||
var rejectSpy3; | ||
beforeEach(function() { | ||
spy1 = sinon.spy(); | ||
spy2 = sinon.spy(); | ||
spy3 = sinon.spy(); | ||
rejectSpy1 = sinon.spy(); | ||
rejectSpy2 = sinon.spy(); | ||
rejectSpy3 = sinon.spy(); | ||
http.get('http://some-url-1').then(spy1).catch(rejectSpy1); | ||
http.get('http://some-url-2').then(spy2).catch(rejectSpy2); | ||
http.get('http://some-url-3').then(spy3).catch(rejectSpy3); | ||
}); | ||
it('records all calls', function() { | ||
expect(http.get.callCount).toBe(3); | ||
expect(http.get.getCall(0).args[0]).toBe('http://some-url-1'); | ||
expect(http.get.getCall(1).args[0]).toBe('http://some-url-2'); | ||
expect(http.get.getCall(2).args[0]).toBe('http://some-url-3'); | ||
}); | ||
describe('#resolve()', function() { | ||
describe('when calling resolve just once', function() { | ||
beforeEach(function() { | ||
http.get.resolve('first'); | ||
}); | ||
describe('when resolved', function() { | ||
it('resolves the first promise, not the others', function() { | ||
expect(spy1.called).toBe(true); | ||
expect(spy2.called).toBe(false); | ||
expect(spy3.called).toBe(false); | ||
}); | ||
}); | ||
}); | ||
describe('when calling #resolve() multiple times', function() { | ||
beforeEach(function() { | ||
http.get.resolve('first'); | ||
http.get.resolve('second'); | ||
}); | ||
describe('when resolved', function() { | ||
it('resolves promises sequentially (first in, first out)', function() { | ||
expect(spy1.called).toBe(true); | ||
expect(spy1.getCall(0).args[0]).toBe('first'); | ||
expect(spy2.called).toBe(true); | ||
expect(spy2.getCall(0).args[0]).toBe('second'); | ||
expect(spy3.called).toBe(false); | ||
}); | ||
}); | ||
}); | ||
describe('when calling #resolve() more times than there are calls remaining', function() { | ||
beforeEach(function() { | ||
http.get.resolve('first'); | ||
http.get.resolve('second'); | ||
http.get.resolve('third'); | ||
}); | ||
it('it throws an error', function() { | ||
try { | ||
http.get.resolve('fourth, will cause an error'); | ||
} catch (e) { | ||
expect(e).toEqual('Resolve cannot be called when there are no more promises to resolve/reject'); | ||
} | ||
}); | ||
}); | ||
describe('when calling #reject() more times than there are calls remaining', function() { | ||
beforeEach(function() { | ||
http.get.reject('first'); | ||
http.get.reject('second'); | ||
http.get.reject('third'); | ||
}); | ||
it('it throws an error', function() { | ||
try { | ||
http.get.reject('fourth, will cause an error'); | ||
} catch (e) { | ||
expect(e).toEqual('Reject cannot be called when there are no more promises to resolve/reject'); | ||
} | ||
}); | ||
}); | ||
}); | ||
describe('#reject()', function() { | ||
describe('when calling #reject() just once', function() { | ||
beforeEach(function() { | ||
http.get.reject('first'); | ||
}); | ||
describe('when rejected', function() { | ||
it('reject the first promise, not the others', function() { | ||
expect(rejectSpy1.called).toBe(true); | ||
expect(rejectSpy2.called).toBe(false); | ||
expect(rejectSpy3.called).toBe(false); | ||
}); | ||
}); | ||
}); | ||
describe('when calling #reject() twice and #resolve() once', function() { | ||
beforeEach(function() { | ||
http.get.reject('error1'); | ||
http.get.resolve('no-error'); | ||
http.get.reject('error2'); | ||
}); | ||
describe('when rejected/resolved', function() { | ||
it('reject promises sequentially', function() { | ||
expect(rejectSpy1.called).toBe(true); | ||
expect(rejectSpy1.getCall(0).args[0]).toBe('error1'); | ||
expect(spy2.called).toBe(true) | ||
expect(spy2.getCall(0).args[0]).toBe('no-error'); | ||
expect(rejectSpy3.called).toBe(true); | ||
expect(rejectSpy3.getCall(0).args[0]).toBe('error2'); | ||
}); | ||
}); | ||
}); | ||
}); | ||
}); | ||
describe('multiple invocation by re-instantiation', function() { | ||
@@ -89,0 +251,0 @@ |
13427
301
108