如何模拟控制器?

时间:2019-12-13 08:53:09

标签: node.js typescript mocha sinon

我不知道该如何嘲笑。有人可以帮我吗?

我想为此控制器编写测试用例。但是我对此并不陌生,所以我从哪里开始以及如何编写我不理解的测试用例。

import { Route } from '../common/ExpressWrapper';
import {partnerDao} from '../factory/AppFactory';
import { keysToLowerCase } from '../util/TpsUtil';
import ErrorResponse from '../models/common/ErrorResponse'

const constants = require('../constants');
const logger = require('../logger/index.ts')('controller/PartnerController');

const GetPartnerByPKController: Route = (req, res) => {
    logger.debug("Entering GetPartnerByPKController()");
    let uuid = req.params.uuid;
    console.time("TimeTaken:DBCall:");
    console.log("Entering GetPartnerByPKController()"+uuid);
    partnerDao.getPartnerByUuid(uuid).then(result => {
        if (result != undefined) {
            res.status(200).send(result);
        } else {
            logger.info("Partner for the uuid:" + uuid + " was not found");
            res.status(404).send(new ErrorResponse("Partner not found", "404.1.100", constants.ERROR_LINK + "404.1.100", []));
        }
    }).catch(error => {
        console.log("Error in accessing GetPartnerByPK API", JSON.stringify(error))
        logger.error("Error in accessing GetPartnerByPK API", JSON.stringify(error));
        res.status(500).send(new ErrorResponse("Internal Server Error", "500.1.103", constants.ERROR_LINK + "500.1.103", [JSON.stringify(error.message)]));
    });
    console.timeEnd("TimeTaken:DBCall:");
    logger.debug("Leaving GetPartnerByPKController()");
}

1 个答案:

答案 0 :(得分:0)

这是单元测试解决方案:

controller.ts

import { partnerDao } from "./AppFactory";
import ErrorResponse from "./ErrorResponse";

type Route = any;

const constants = {
  ERROR_LINK: "ERROR_LINK",
};

export const GetPartnerByPKController: Route = async (req, res) => {
  console.debug("Entering GetPartnerByPKController()");
  let uuid = req.params.uuid;
  console.time("TimeTaken:DBCall:");
  console.log("Entering GetPartnerByPKController()" + uuid);
  await partnerDao
    .getPartnerByUuid(uuid)
    .then((result) => {
      if (result != undefined) {
        res.status(200).send(result);
      } else {
        console.info("Partner for the uuid:" + uuid + " was not found");
        res
          .status(404)
          .send(new ErrorResponse("Partner not found", "404.1.100", constants.ERROR_LINK + "404.1.100", []));
      }
    })
    .catch((error) => {
      console.log("Error in accessing GetPartnerByPK API", JSON.stringify(error));
      console.error("Error in accessing GetPartnerByPK API", JSON.stringify(error));
      res
        .status(500)
        .send(
          new ErrorResponse("Internal Server Error", "500.1.103", constants.ERROR_LINK + "500.1.103", [
            JSON.stringify(error.message),
          ]),
        );
    });
  console.timeEnd("TimeTaken:DBCall:");
  console.debug("Leaving GetPartnerByPKController()");
};

AppFactory.ts

export const partnerDao = {
  async getPartnerByUuid(id) {
    return "real data";
  },
};

ErrorResponse.ts

export default class ErrorResponse {
  public desc = "";
  public args: any;
  public code: string = "";
  public message: string = "";
  constructor(message, code, desc, args) {
    this.message = message;
    this.desc = desc;
    this.args = args;
    this.code = code;
  }
}

controller.test.ts

import { GetPartnerByPKController } from "./controller";
import { partnerDao } from "./AppFactory";
import sinon from "sinon";
import { expect } from "chai";
import ErrorResponse from "./ErrorResponse";

describe("GetPartnerByPKController", () => {
  afterEach(() => {
    sinon.restore();
  });
  it("should get parter by uuid correctly", async () => {
    const mResponse = "fake data";
    const getPartnerByUuidStub = sinon.stub(partnerDao, "getPartnerByUuid").resolves(mResponse);
    const mReq = { params: { uuid: "123" } };
    const mRes = { status: sinon.stub().returnsThis(), send: sinon.stub() };
    await GetPartnerByPKController(mReq, mRes);
    sinon.assert.calledWith(mRes.status, 200);
    sinon.assert.calledWith(mRes.status().send, mResponse);
    sinon.assert.calledWith(getPartnerByUuidStub, "123");
  });

  it("should 404", async () => {
    const mResponse = undefined;
    const getPartnerByUuidStub = sinon.stub(partnerDao, "getPartnerByUuid").resolves(mResponse);
    const mReq = { params: { uuid: "123" } };
    const mRes = { status: sinon.stub().returnsThis(), send: sinon.stub() };
    await GetPartnerByPKController(mReq, mRes);
    sinon.assert.calledWith(mRes.status, 404);
    sinon.assert.calledWith(
      mRes.status().send,
      new ErrorResponse("Partner not found", "404.1.100", "ERROR_LINK" + "404.1.100", []),
    );
    sinon.assert.calledWith(getPartnerByUuidStub, "123");
  });

  it("should 500", async () => {
    const mError = new Error("unknown error");
    const getPartnerByUuidStub = sinon.stub(partnerDao, "getPartnerByUuid").rejects(mError);
    const mReq = { params: { uuid: "123" } };
    const mRes = { status: sinon.stub().returnsThis(), send: sinon.stub() };
    await GetPartnerByPKController(mReq, mRes);
    sinon.assert.calledWith(mRes.status, 500);
    sinon.assert.calledWith(
      mRes.status().send,
      new ErrorResponse("Internal Server Error", "500.1.103", "ERROR_LINK" + "500.1.103", [
        JSON.stringify(mError.message),
      ]),
    );
    sinon.assert.calledWith(getPartnerByUuidStub, "123");
  });
});

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

  GetPartnerByPKController
Entering GetPartnerByPKController()
Entering GetPartnerByPKController()123
TimeTaken:DBCall:: 21.633ms
Leaving GetPartnerByPKController()
    ✓ should get parter by uuid correctly
Entering GetPartnerByPKController()
Entering GetPartnerByPKController()123
Partner for the uuid:123 was not found
TimeTaken:DBCall:: 0.532ms
Leaving GetPartnerByPKController()
    ✓ should 404
Entering GetPartnerByPKController()
Entering GetPartnerByPKController()123
Error in accessing GetPartnerByPK API {}
Error in accessing GetPartnerByPK API {}
TimeTaken:DBCall:: 35.619ms
Leaving GetPartnerByPKController()
    ✓ should 500 (38ms)


  3 passing (124ms)

--------------------|----------|----------|----------|----------|-------------------|
File                |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
--------------------|----------|----------|----------|----------|-------------------|
All files           |    98.51 |      100 |    91.67 |    98.41 |                   |
 AppFactory.ts      |       50 |      100 |        0 |       50 |                 3 |
 ErrorResponse.ts   |      100 |      100 |      100 |      100 |                   |
 controller.test.ts |      100 |      100 |      100 |      100 |                   |
 controller.ts      |      100 |      100 |      100 |      100 |                   |
--------------------|----------|----------|----------|----------|-------------------|

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