Skip to content

Commit

Permalink
Add passThroughByDefault option
Browse files Browse the repository at this point in the history
  • Loading branch information
Anatoliy Ostapenko committed Jan 10, 2020
1 parent 71cd221 commit 914979f
Show file tree
Hide file tree
Showing 6 changed files with 191 additions and 12 deletions.
15 changes: 13 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ Mock a low level network error
// Returns a failed promise with Error('Network Error');
mock.onGet('/users').networkError();

// networkErrorOnce can be used to mock a network error only once
// networkErrorOnce can be used to mock a network error only once
mock.onGet('/users').networkErrorOnce();
```

Expand All @@ -110,7 +110,7 @@ Mock a network timeout
// Returns a failed promise with Error with code set to 'ECONNABORTED'
mock.onGet('/users').timeout();

// timeoutOnce can be used to mock a timeout only once
// timeoutOnce can be used to mock a timeout only once
mock.onGet('/users').timeoutOnce();
```

Expand Down Expand Up @@ -245,6 +245,17 @@ mock

Note that `passThrough` requests are not subject to delaying by `delayResponse`.

If you set `passThroughByDefault` option all requests would be forwarded over network by default

```js
// Mock all requests to /foo with HTTP 200, but forward
// any others requests to server
var mock = new MockAdapter(axiosInstance, { passThroughByDefault: true });

mock
.onAny('/foo').reply(200);
```

As of 1.7.0, `reply` function may return a Promise:

```js
Expand Down
22 changes: 13 additions & 9 deletions src/handle_request.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,19 @@ function handleRequest(mockAdapter, resolve, reject, config) {
}
} else {
// handler not found
utils.settle(
resolve,
reject,
{
status: 404,
config: config
},
mockAdapter.delayResponse
);
if (mockAdapter.passThroughByDefault) {
mockAdapter.originalAdapter(config).then(resolve, reject);
} else {
utils.settle(
resolve,
reject,
{
status: 404,
config: config
},
mockAdapter.delayResponse
);
}
}
}

Expand Down
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ function MockAdapter(axiosInstance, options) {
this.axiosInstance = axiosInstance;
this.originalAdapter = axiosInstance.defaults.adapter;
this.delayResponse = options && options.delayResponse > 0 ? options.delayResponse : null;
this.passThroughByDefault = !!(options && options.passThroughByDefault);
axiosInstance.defaults.adapter = this.adapter.call(this);
}
}
Expand Down
161 changes: 161 additions & 0 deletions test/pass_through_by_default.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
var axios = require('axios');
var expect = require('chai').expect;
var createServer = require('http').createServer;

var MockAdapter = require('../src');

describe('passThroughByDefault option tests (requires Node)', function() {
var instance;
var mock;
var httpServer;
var serverUrl;

before('set up Node server', function() {
return new Promise(function(resolve, reject) {
httpServer = createServer(function(req, resp) {
if (req.url === '/error') {
resp.statusCode = 500;
resp.end();
} else {
resp.statusCode = 200;
// Reply with path
resp.end(req.url, 'utf8');
}
})
.listen(0, '127.0.0.1', function() {
serverUrl = 'http://127.0.0.1:' + httpServer.address().port;
resolve();
})
.on('error', reject);
});
});

after(function() {
httpServer.close();
});

beforeEach(function() {
instance = axios.create({ baseURL: serverUrl });
mock = new MockAdapter(instance, { passThroughByDefault: true });
});

it('works correctly if set no handlers', function() {
var randomPath = 'xyz' + Math.round(10000 * Math.random());

return Promise.all([
instance.get('/' + randomPath).then(function(response) {
expect(response.status).to.equal(200);
expect(response.data).to.equal('/' + randomPath);
})
]);
});

it('allows selective mocking', function() {
mock.onGet('/foo').reply(200, 'bar');
mock.onGet('/error').reply(200, 'success');
mock.onGet('/bar').passThrough();

var randomPath = 'xyz' + Math.round(10000 * Math.random());

return Promise.all([
instance.get('/foo').then(function(response) {
expect(response.status).to.equal(200);
expect(response.data).to.equal('bar');
}),
instance.get('/error').then(function(response) {
expect(response.status).to.equal(200);
expect(response.data).to.equal('success');
}),
instance.get('/bar').then(function(response) {
expect(response.status).to.equal(200);
expect(response.data).to.equal('/bar');
}),
instance.get('/' + randomPath).then(function(response) {
expect(response.status).to.equal(200);
expect(response.data).to.equal('/' + randomPath);
})
]);
});

it('handles errors correctly', function() {
return instance
.get('/error')
.then(function() {
// The server should've returned an error
expect(false).to.be.true;
})
.catch(function(error) {
expect(error).to.have.nested.property('response.status', 500);
});
});

it('setting passThrough handler don\'t break anything', function() {
mock
.onGet('/foo')
.reply(200, 'bar')
.onAny()
.passThrough();

var randomPath = 'xyz' + Math.round(10000 * Math.random());

return Promise.all([
instance.get('/foo').then(function(response) {
expect(response.status).to.equal(200);
expect(response.data).to.equal('bar');
}),
instance.get('/' + randomPath).then(function(response) {
expect(response.status).to.equal(200);
expect(response.data).to.equal('/' + randomPath);
}),
instance.post('/post').then(function(response) {
expect(response.status).to.equal(200);
expect(response.data).to.equal('/post');
})
]);
});

it('handles baseURL correctly', function() {
instance = axios.create({
baseURL: '/test',
proxy: {
host: '127.0.0.1',
port: httpServer.address().port
}
});
mock = new MockAdapter(instance, { passThroughByDefault: true });

return instance.get('/foo').then(function(response) {
expect(response.status).to.equal(200);
expect(response.data).to.equal('http://null/test/foo');
});
});

it('handles request transformations properly', function() {
return instance
.get('/foo', {
data: 'foo',
transformRequest: [
function(data) {
return data + 'foo';
}
]
})
.then(function(response) {
expect(response.config.data).to.equal('foofoo');
});
});

it('handles response transformations properly', function() {
return instance
.get('/foo', {
transformResponse: [
function(data) {
return data + 'foo';
}
]
})
.then(function(response) {
expect(response.data).to.equal('/foofoo');
});
});
});
1 change: 1 addition & 0 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ interface RequestHandler {

interface MockAdapterOptions {
delayResponse?: number;
passThroughByDefault?: boolean;
}

interface RequestDataMatcher {
Expand Down
3 changes: 2 additions & 1 deletion types/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ namespace AllowsConstructing {

namespace AllowsConstructingWithOptions {
new MockAdapter(instance, {
delayResponse: 2000
delayResponse: 2000,
passThroughByDefault: true
});
}

Expand Down

0 comments on commit 914979f

Please # to comment.