npm install --save-dev mock4xhr
npm install --save mock4xhr
./createUser.js
// you could just as easily use Axios, jQuery, Superagent or another package here instead of using the native XMLHttpRequest object
export default function(data) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState == XMLHttpRequest.DONE) {
if (xhr.status === 201) {
resolve(JSON.parse(xhr.responseText).data);
} else {
reject(JSON.parse(xhr.responseText).error);
}
}
}
xhr.open('post', '/api/user');
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify({data: data}))
});
}
component install jameslnewell/mock4xhr
`./createUser.test.js`
```js
import mock from 'mock4xhr';
import createUser from './createUser';
```javascript
var mock = require('mock4xhr');
// replace the real XHR object with the mock XHR object before each test
beforeEach(() => mock.setup());
// put the real XHR object back and clear the mocks after each test
afterEach(() => mock.teardown());
it('should send the data as JSON', () => {
mock.post('/api/user', (req, res) => {
expect(req.header('Content-Type')).to.equal('application/json');
expect(req.body()).to.equal('{"foo":"bar"');
return res;
});
return createUser({name: 'John'});
});
it('should resolve with some data when status=201', () => {
mock.post('/api/user', {
status: 201,
reason: 'Created',
body: '{"data":{"id":"abc-123"}}'
});
return expect(createUser({name: 'John'})).to.eventually.deep.equal({id: 'abc-123'});
});
it('should reject with an error when status=400', () => {
mock.post('/api/user', {
status: 400,
reason: 'Bad Request',
body: '{"error":"A user named \\"John\\" already exists."}'
});
return expect(createUser({name: 'John'})).to.be.rejectedWith(Error)
});
});
Examples of using mock4xhr
with various frameworks:
Replace the global XMLHttpRequest
object with the MockXMLHttpRequest
.
Restore the global XMLHttpRequest
object to its original state.
Forget all the request handlers.
Register a factory function to create mock responses for each GET request to a specific URL.
Register a factory function to create mock responses for each POST request to a specific URL.
Register a factory function to create mock responses for each PUT request to a specific URL.
Register a factory function to create mock responses for each PATCH request to a specific URL.
Register a factory function to create mock responses for each DELETE request to a specific URL.
Register a factory function to create mock responses for each request to a specific URL.
Register a factory function to create mock responses for every request.
Get the request method.
Get the request URL.
Get a request header.
Get the request headers.
Get the request body.
Get the response status.
Set the response status.
Get the response reason.
Set the response reason.
Set a response header.
Get a response header.
Get the response headers.
Set the response headers.
Get the response body.
Set the response body.
Set the Content-Length
header and send a body. mock4xhr
will emit ProgressEvent
s.
import mock from 'mock4xhr';
mock.setup();
mock.get('/', {});
const xhr = new XMLHttpRequest();
xhr.upload.onprogress = event => {
console.log(event.loaded, event.total);
};
xhr.onloadend = event => {
mock.teardown();
};
xhr.open('GET', '/');
xhr.setRequestHeader('Content-Type', '12');
xhr.send('Hello World!');
const xhr = new XMLHttpRequest(); xhr.timeout = 100; xhr.ontimeout = event => { console.log('timeout'); }; xhr.open('GET', '/'); xhr.send();
> A number of major libraries don't use the `timeout` event and use `setTimeout()` instead. Therefore, in order to mock timeouts in major libraries, we have to wait for the specified amount of time anyway.
### Simulate an error
Return a `Promise` that rejects.
```js
import mock from 'mock4xhr';
mock.post('/', (req, res) => {
return new Promise.reject();
});
const xhr = new XMLHttpRequest();
xhr.onerror = event => {
console.log(event.error);
};
xhr.open('GET', '/');
xhr.send();
If you want to mock some requests but not all of them, you can proxy unhandled requests to a real server.
import mock from 'mock4xhr';
// mock specific requests
mock.post('/', (req, res) => {
return res.status(204);
});
// other requests will be proxied to the actual server
mock.mock((req, res) => {
return fetch(req.url(), {
method: req.method(),
headers: req.headers(),
body: req.body()
})
.then(r => {
return r.text().then(text => {
return res
.status(r.statusCode)
.headers(r.headers.entries().reduce((headers, pair) => {
headers[pair[0]] = pair[1];
}))
.body(text)
;
});
})
;
});