You should use a stub/mock library such as sinonjs. So that you can stub the side effect operations such as HTTP requests, events. Unit tests should be running in an isolated environment. Which means there should not have HTTP requests via the real network.
We stub https.get
and resp.on
methods with fake implementations. Then we call data
event and end
event later manually.
In addition, we clean the module cache in order to prevent the cache from affecting the test results.
E.g.
app.js
:
const https = require('https');
let endPoint = 'https://dog.ceo/api/breeds/list/all';
https
.get(endPoint, (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
resp.on('end', () => {
console.log(JSON.parse(data).message);
console.log(JSON.parse(data).status);
});
})
.on('error', (err) => {
console.log('Error: ' + err.message);
});
app.test.js
:
const https = require('https');
const sinon = require('sinon');
describe('66055952', () => {
beforeEach(() => {
delete require.cache[require.resolve('./app')];
});
afterEach(() => {
sinon.restore();
});
it('should get and print data', () => {
let onDataCallback;
let onEndCallback;
const resp = {
on: sinon.stub().callsFake((event, callback) => {
if (event === 'data') {
onDataCallback = callback;
} else if (event === 'end') {
onEndCallback = callback;
}
}),
};
const httpsContext = { on: sinon.stub() };
sinon.stub(https, 'get').callsFake((endpoint, callback) => {
callback(resp);
return httpsContext;
});
const logSpy = sinon.stub(console, 'log');
require('./app');
onDataCallback('{ "message"');
onDataCallback(': "teresa teng", "status": 200 }');
onEndCallback();
sinon.assert.calledWith(https.get, 'https://dog.ceo/api/breeds/list/all', sinon.match.func);
sinon.assert.calledWith(httpsContext.on, 'error', sinon.match.func);
sinon.assert.calledWith(logSpy, 'teresa teng');
sinon.assert.calledWith(logSpy, 200);
});
it('should handle error', () => {
const err = new Error('network');
const httpsContext = {
on: sinon.stub().callsFake((event, callback) => {
callback(err);
}),
};
sinon.stub(https, 'get').returns(httpsContext);
const logStub = sinon.stub(console, 'log');
require('./app');
sinon.assert.calledWith(logStub, 'Error: network');
});
});
unit test result:
66055952
? should get and print data
? should handle error
2 passing (9ms)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
app.js | 100 | 100 | 100 | 100 |
----------|---------|----------|---------|---------|-------------------
package versions:
"mocha": "^8.2.1",
"sinon": "^8.1.1"
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…