From 13c43f94025b29726bb9e61701f7a3c185f52aab Mon Sep 17 00:00:00 2001 From: Alon Burg Date: Tue, 21 Aug 2018 11:55:01 +0300 Subject: [PATCH] return handler in reply(...) mocks in order to allow removing handler, and monitoring calls --- README.md | 5 +++- src/handle_request.js | 1 + src/index.js | 13 +++++++--- test/basics.spec.js | 53 +++++++++++++++++++++++---------------- test/pass_through.spec.js | 5 ++-- test/reply_once.spec.js | 17 ++----------- 6 files changed, 50 insertions(+), 44 deletions(-) diff --git a/README.md b/README.md index 58f7e36..b553b38 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ var mock = new MockAdapter(axios); // Mock any GET request to /users // arguments for reply are (status, data, headers) -mock.onGet('/users').reply(200, { +var handler = mock.onGet('/users').reply(200, { users: [ { id: 1, name: 'John Smith' } ] @@ -41,6 +41,9 @@ axios.get('/users') .then(function(response) { console.log(response.data); }); + +// Assert mock was called +expect(handler.called).to.equal(1); ``` Mocking a `GET` request with specific parameters diff --git a/src/handle_request.js b/src/handle_request.js index 937a9d0..b9ddc3a 100644 --- a/src/handle_request.js +++ b/src/handle_request.js @@ -31,6 +31,7 @@ function handleRequest(mockAdapter, resolve, reject, config) { ); if (handler) { + handler.called++; if (handler.length === 7) { utils.purgeIfReplyOnce(mockAdapter, handler); } diff --git a/src/index.js b/src/index.js index d55517b..4be6d9a 100644 --- a/src/index.js +++ b/src/index.js @@ -2,6 +2,7 @@ var deepEqual = require('deep-equal'); +var utils = require('./utils'); var handleRequest = require('./handle_request'); var VERBS = ['get', 'post', 'head', 'delete', 'patch', 'put', 'options', 'list']; @@ -54,6 +55,10 @@ function MockAdapter(axiosInstance, options) { MockAdapter.prototype.adapter = adapter; +MockAdapter.prototype.removeHandler = function removeHanlder(handler) { + utils.purgeIfReplyOnce(this, handler); +}; + MockAdapter.prototype.restore = function restore() { if (this.axiosInstance) { this.axiosInstance.defaults.adapter = this.originalAdapter; @@ -73,13 +78,13 @@ VERBS.concat('any').forEach(function(method) { function reply(code, response, headers) { var handler = [matcher, body, requestHeaders, code, response, headers]; addHandler(method, _this.handlers, handler); - return _this; + return handler; } function replyOnce(code, response, headers) { var handler = [matcher, body, requestHeaders, code, response, headers, true]; addHandler(method, _this.handlers, handler); - return _this; + return handler; } return { @@ -90,7 +95,7 @@ VERBS.concat('any').forEach(function(method) { passThrough: function passThrough() { var handler = [matcher, body]; addHandler(method, _this.handlers, handler); - return _this; + return handler; }, networkError: function() { @@ -151,6 +156,8 @@ function findInHandlers(method, handlers, handler) { } function addHandler(method, handlers, handler) { + handler.called = 0; + // const handler = originalHandler if (method === 'any') { VERBS.forEach(function(verb) { handlers[verb].push(handler); diff --git a/test/basics.spec.js b/test/basics.spec.js index d1d6dfa..c09d5c5 100644 --- a/test/basics.spec.js +++ b/test/basics.spec.js @@ -101,8 +101,8 @@ describe('MockAdapter basics', function() { it('accepts a callback that returns an axios request', function() { mock .onGet('/bar') - .reply(200, { foo: 'bar' }) - .onGet('/foo') + .reply(200, { foo: 'bar' }); + mock.onGet('/foo') .reply(function() { return instance.get('/bar'); }); @@ -216,6 +216,18 @@ describe('MockAdapter basics', function() { }); }); + it('allow removing mock handler', function() { + const handler = mock.onGet('/').reply(200); + return instance.get('/').then(function(response) { + expect(response.status).to.equal(200); + mock.removeHandler(handler); + return instance.get('/'); + }).catch(function(error) { + expect(error.response.status).to.equal(404); + expect(handler.called).to.equal(1); + }); + }); + it('matches when parameters were not expected', function() { mock.onGet('/withParams').reply(200); return instance @@ -466,10 +478,10 @@ describe('MockAdapter basics', function() { it('can chain calls to add mock handlers', function() { mock .onGet('/foo') - .reply(200) - .onAny('/bar') - .reply(404) - .onPost('/baz') + .reply(200); + mock.onAny('/bar') + .reply(404); + mock.onPost('/baz') .reply(500); expect(mock.handlers['get'].length).to.equal(2); @@ -510,10 +522,9 @@ describe('MockAdapter basics', function() { }); it('maps empty GET path to any path', function() { - mock - .onGet('/foo') - .reply(200, 'foo') - .onGet() + mock.onGet('/foo') + .reply(200, 'foo'); + mock.onGet() .reply(200, 'bar'); return Promise.all([ @@ -636,14 +647,13 @@ describe('MockAdapter basics', function() { }); it('supports chaining on same path with different params', function() { - mock - .onGet('/users', { params: { searchText: 'John' } }) - .reply(200, { id: 1 }) - .onGet('/users', { params: { searchText: 'James' } }) - .reply(200, { id: 2 }) - .onGet('/users', { params: { searchText: 'Jake' } }) - .reply(200, { id: 3 }) - .onGet('/users', { params: { searchText: 'Jackie' } }) + mock.onGet('/users', { params: { searchText: 'John' } }) + .reply(200, { id: 1 }); + mock.onGet('/users', { params: { searchText: 'James' } }) + .reply(200, { id: 2 }); + mock.onGet('/users', { params: { searchText: 'Jake' } }) + .reply(200, { id: 3 }); + mock.onGet('/users', { params: { searchText: 'Jackie' } }) .reply(200, { id: 4 }); return instance @@ -739,10 +749,9 @@ describe('MockAdapter basics', function() { }); it('allows overwriting mocks with parameters', function() { - mock - .onGet('/users', { params: { searchText: 'John' } }) - .reply(500) - .onGet('/users', { params: { searchText: 'John' } }) + mock.onGet('/users', { params: { searchText: 'John' } }) + .reply(500); + mock.onGet('/users', { params: { searchText: 'John' } }) .reply(200, { id: 1 }); return instance diff --git a/test/pass_through.spec.js b/test/pass_through.spec.js index 8f5c255..73767a7 100644 --- a/test/pass_through.spec.js +++ b/test/pass_through.spec.js @@ -85,9 +85,8 @@ describe('passThrough tests (requires Node)', function() { }); it('allows setting default passThrough handler', function() { - mock - .onGet('/foo').reply(200, 'bar') - .onAny().passThrough(); + mock.onGet('/foo').reply(200, 'bar'); + mock.onAny().passThrough(); var randomPath = 'xyz' + Math.round(10000 * Math.random()); diff --git a/test/reply_once.spec.js b/test/reply_once.spec.js index 7e31059..c7fe7e5 100644 --- a/test/reply_once.spec.js +++ b/test/reply_once.spec.js @@ -12,19 +12,6 @@ describe('MockAdapter replyOnce', function() { mock = new MockAdapter(instance); }); - it('supports chaining', function() { - mock - .onGet('/foo') - .replyOnce(200) - .onAny('/foo') - .replyOnce(500) - .onPost('/foo') - .replyOnce(201); - - expect(mock.handlers['get'].length).to.equal(2); - expect(mock.handlers['post'].length).to.equal(2); - }); - it('replies as normally on the first call', function() { mock.onGet('/foo').replyOnce(200, { foo: 'bar' @@ -90,8 +77,8 @@ describe('MockAdapter replyOnce', function() { .onGet('/foo') .replyOnce(function() { return [200]; - }) - .onGet('/foo') + }); + mock.onGet('/foo') .replyOnce(function() { return [202]; });