Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
146 views
in Technique[技术] by (71.8m points)

Sample Unit Test in Node.Js

I am learning Node.js and this is my first node js app with HTTPS. This app is working fine but I need some help with the writing unit tests for this.

I have a simple node.js app that will fetch some dog breed and will populate. I want to write a unit test for this app which will assert if the response is not null and has some JSON value.

I know there are lots of test frameworks but I wanted to write a simple test suite in the Mocha framework.

HttpApp.js

const https = require('https');
let endPoint = 'https://dog.ceo/api/breeds/list/all';

https.get(endPoint, (resp) => {
  let data = '';

  // A chunk of data has been received.
  resp.on('data', (chunk) => {
    data += chunk;
  });

  // The whole response has been received. Print out the result.
  resp.on('end', () => {
    //console.log(JSON.parse(data).explanation);
    console.log(JSON.parse(data).message);
    console.log(JSON.parse(data).status);
    //console.log(data.media_type);
  });

}).on("error", (err) => {
  console.log("Error: " + err.message);
});
question from:https://stackoverflow.com/questions/66055952/sample-unit-test-in-node-js

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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"

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...