无法调用res.send()

问题描述 投票:0回答:1

我正在开发Node.js应用程序。

这是validate.js文件的代码,我在其中定义了一个类Validate和静态方法validateTicket,并在底部导出了该类。

validate.js文件

const request = require("request");
const config = { urlBase: "" };

class Validate {
  static validateTicket = (ticket) => {
    const options = { url: config.urlBase + ticket, json: true, rejectUnauthorized: false };

    return new Promise((resolve, reject) => {
      request.get(options, (error, response, body) => {
        if (error) {
          reject(error);
          return;
        }

        if (response) {
          resolve(response);
          return;
        }

        reject(null);
      });
    });
  };
}

module.exports = Validate;

这是我要导入validate.js文件的主要实用程序文件,并且有3个函数validateTicketReqsto_jsonsendErrorResponse

[validateTicketReqs函数对从类方法收到的响应进行验证。

util.js文件

const validate = require('./validate.js');

function validateTicketReqs(req, res, next, flag, num) {

    let payload = req.body;
    let ticket= (payload.ticket) ? payload.ticket: null;
    let error_msg = 'Failed to obtain a successful response '

    validate.validateTicket(ticket).then(
        (resolution) => {
            let json = to_json(resolution); // function will return null value for json
            if (json === null || !('body' in json)) {
                return sendErrorResponse(req, res, 500, 'error');
            }
            ...
            })

function sendErrorResponse(req, res, code, msg) {
    let resBody = {
        msg: msg
    };

    res.status(code);
    res.send(resBody);
}

test_util.js文件

const validate = require('./validate.js');
describe("Check", () => {


        it("should fail due to error", (done) => {
            let req  = {
            authData: {'user_id': "mock"},
            body: {"num": "mock", "tikcet": "mock"},
            request_id: 'mock'
        }; 
            let res = {send: sinon.spy(), status: sinon.spy()};
            let next = sinon.spy();

            mock_buffer =  {
                toJSON : function() { return {body: {environment: 'mock', status: 'mock'}}},
                statusCode: 500
            }
            const validateTicket= sinon.stub(validate, 'validateTicket')
            validateTicket.resolves(mock_buffer)

            util.valdateTicketReqs(req, res, next, flag, "mock" );

            expect(res.send.calledOnce).to.be.true; ##not getting called
            expect(res.send.firstCall.args[0].statusCode).to.equal(500); ##not getting called


            util.valdateTicketReqs.restore();

            validate.validateTicket.restore();
            done();
        });



    });

我面临的问题是(res.send.calledOnce)值即将变为假。我期望res.send()应该至少被调用一次,但不是。请在这里告知问题所在。让我知道您是否对此问题有疑问。

javascript node.js chai sinon
1个回答
0
投票

问题是在测试用例完成之前调用了expect方法。您的validate.validateTicket方法的返回值是一个promise,它是异步方法。您需要将其返回,以便测试运行程序知道测试用例是否完成。

例如

validate.ts

const request = require("request");
const config = { urlBase: "" };

class Validate {
  static validateTicket = (ticket) => {
    const options = { url: config.urlBase + ticket, json: true, rejectUnauthorized: false };

    return new Promise((resolve, reject) => {
      request.get(options, (error, response, body) => {
        if (error) {
          reject(error);
          return;
        }

        if (response) {
          resolve(response);
          return;
        }

        reject(null);
      });
    });
  };
}

module.exports = Validate;

util.ts

const validate = require("./validate");

function to_json(data) {
  return null;
}

function sendErrorResponse(req, res, code, msg) {
  const resBody = {
    msg: msg,
  };
  res.status(code);
  res.send(resBody);
}

export function validateTicketReqs(req, res, next, flag, num) {
  const payload = req.body;
  const ticket = payload.ticket ? payload.ticket : null;
  const error_msg = "Failed to obtain a successful response ";

  return validate.validateTicket(ticket).then((resolution) => {
    const json = to_json(resolution);
    if (json === null || !("body" in json)) {
      return sendErrorResponse(req, res, 500, "error");
    }
  });
}

util.spec.ts

import sinon from "sinon";
import { expect } from "chai";
import * as util from "./util";
const validate = require("./validate");

describe("Check", () => {
  it("should fail due to error", async () => {
    const req = {
      authData: { user_id: "mock" },
      body: { num: "mock", tikcet: "mock" },
      request_id: "mock",
    };
    const res = {
      send: sinon.spy(),
      status: sinon.spy(),
    };
    const next = sinon.spy();
    const flag = "";

    const mock_buffer = {
      toJSON: function() {
        return { body: { environment: "mock", status: "mock" } };
      },
      statusCode: 500,
    };
    const validateTicketStub = sinon.stub(validate, "validateTicket").resolves(mock_buffer);
    await util.validateTicketReqs(req, res, next, flag, "mock");

    expect(res.send.calledOnce).to.be.true;
    expect(res.status.firstCall.args[0]).to.equal(500);
    sinon.assert.calledOnce(validateTicketStub);
    validateTicketStub.restore();
  });
});

带有覆盖率报告的单元测试结果:

 Check
    ✓ should fail due to error


  1 passing (19ms)

--------------|----------|----------|----------|----------|-------------------|
File          |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
--------------|----------|----------|----------|----------|-------------------|
All files     |    76.09 |       30 |    63.64 |    75.56 |                   |
 util.spec.ts |    94.12 |      100 |    66.67 |    93.75 |                22 |
 util.ts      |      100 |       50 |      100 |      100 |              9,14 |
 validate.ts  |     37.5 |        0 |       25 |     37.5 |... 12,15,16,17,20 |
--------------|----------|----------|----------|----------|-------------------|

源代码:https://github.com/mrdulin/mocha-chai-sinon-codelab/tree/master/src/stackoverflow/59037819

© www.soinside.com 2019 - 2024. All rights reserved.