简体   繁体   English

对具有回调的 function 的 function 进行单元测试(请求模块)

[英]Unit test a function which has a function with callback (request module)

I am making testing in my NodeJS project and I have the following function I want to unit test:我正在我的 NodeJS 项目中进行测试,我有以下 function 我想进行单元测试:

function myRequest(targetUrl, reqBody) {
  return new Promise((resolve, reject) => {
    request.post(targetUrl, { json: reqBody }, (error, response, body) => {
      if (!error && response.statusCode === 200) {
        resolve(body.transferId);
      } else {
        reject(error || body.description || body);
      }
    });
  });
}

I am using mocha and sinon.我正在使用摩卡和西农。 How can I test this function?如何测试这个 function?

Firstly, I tested using my own mocked request module for the success scenario.首先,我使用自己的模拟请求模块对成功场景进行了测试。 Now, I want to do the error scenario, which could be the post function gets an error.现在,我想做错误场景,这可能是 function 后出现错误。 How could I do it without changing or making a new one mock of request (to return an error)?我怎么能在不更改或制作新的请求模拟(返回错误)的情况下做到这一点? Is is possible?有可能吗?

Here is the unit test solution, you should use sinon.stub :这是单元测试解决方案,您应该使用sinon.stub

Eg index.ts :例如index.ts

import request from 'request';

export function myRequest(targetUrl, reqBody) {
  return new Promise((resolve, reject) => {
    request.post(targetUrl, { json: reqBody }, (error, response, body) => {
      if (!error && response.statusCode === 200) {
        resolve(body.transferId);
      } else {
        reject(error || body.description || body);
      }
    });
  });
}

index.spec.ts : index.spec.ts

import { myRequest } from '.';
import chai from 'chai';
import sinon from 'sinon';
import chaiAsPromised from 'chai-as-promised';
import request from 'request';
chai.use(chaiAsPromised);

const { expect } = chai;

describe('myRequest', () => {
  it('should request success', async done => {
    // @ts-ignore
    const stub = sinon.stub(request, 'post').callsFake((uri, options, callback) => {
      const mResponse = { statusCode: 200 };
      const mBody = { transferId: 1 };
      callback(null, mResponse, mBody);
      done();
    });
    const actualValue = await myRequest('url', {});
    // @ts-ignore
    stub.calledOnceWith('url', { json: {} });
    expect(actualValue).to.eq(1);
    stub.restore();
  });

  it('should throw error use request error', async done => {
    const mError = new Error('Internal server error');
    const mResponse = { statusCode: 500 };
    // @ts-ignore
    const stub = sinon.stub(request, 'post').callsFake((uri, options, callback) => {
      callback(mError, mResponse, null);
      done();
    });
    await expect(myRequest('url', {})).to.be.rejectedWith(mError);
    // @ts-ignore
    stub.calledOnceWith('url', { json: {} });
    stub.restore();
  });

  it('should throw error use body.description as error message', async done => {
    const mResponse = { statusCode: 500 };
    const mBody = { description: 'some error' };
    // @ts-ignore
    const stub = sinon.stub(request, 'post').callsFake((uri, options, callback) => {
      callback(null, mResponse, mBody);
      done();
    });
    await expect(myRequest('url', {})).to.be.rejectedWith(mBody.description);
    // @ts-ignore
    stub.calledOnceWith('url', { json: {} });
    stub.restore();
  });

  it('should throw error use body as error message', async done => {
    const mResponse = { statusCode: 500 };
    const mBody = 'some error';
    // @ts-ignore
    const stub = sinon.stub(request, 'post').callsFake((uri, options, callback) => {
      callback(null, mResponse, mBody);
      done();
    });
    await expect(myRequest('url', {})).to.be.rejectedWith(mBody);
    // @ts-ignore
    stub.calledOnceWith('url', { json: {} });
    stub.restore();
  });
});

Unit test result with 100% coverage:覆盖率 100% 的单元测试结果:

  myRequest
    ✓ should request success
    ✓ should throw error use request error
    ✓ should throw error use body.description as error message
    ✓ should throw error use body as error message


  4 passing (13ms)

---------------|----------|----------|----------|----------|-------------------|
File           |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
---------------|----------|----------|----------|----------|-------------------|
All files      |      100 |      100 |      100 |      100 |                   |
 index.spec.ts |      100 |      100 |      100 |      100 |                   |
 index.ts      |      100 |      100 |      100 |      100 |                   |
---------------|----------|----------|----------|----------|-------------------|

Source code: https://github.com/mrdulin/mocha-chai-sinon-codelab/tree/master/src/stackoverflow/58822996源码: https://github.com/mrdulin/mocha-chai-sinon-codelab/tree/master/src/stackoverflow/58822996

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 测试在哪个函数中执行回调 - Test in which function a callback is executed 如何使用Angular对带有promise和回调函数的函数进行单元测试 - How to unit test a function with a promise and callback function with Angular 使用 sinon 对带有 got 模块的函数进行单元测试 - Unit Test for a function with got module using sinon 有没有功能来测试在js中具有回调的对象实例? - is there a function to test an object instance that has a callback in js? 单元测试请求-Promise,promise()不是函数 - Unit test request-promise, promise() is not a function 如何从作为模块导出的请求中获取回调函数的返回值 - How to get the return value of the callback function from a request which is exported as a module NodeJS - 回调 function 中的断言没有失败 Mocha 单元测试 - NodeJS - Assertion in callback function not failing Mocha unit test 如何使用 Cypress 对在 React 组件上调用的回调函数进行单元测试 - How to unit test a callback function was called on a React component using Cypress 如何使用sinon.js对回调函数的内容进行单元测试 - how to unit test contents of a callback function with sinon.js Javascript单元测试,测试击中函数内部的回调 - Javascript unit tesing, test hitting a callback inside function
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM