node-mocks-http icon indicating copy to clipboard operation
node-mocks-http copied to clipboard

how to create error response?

Open vejandla opened this issue 10 months ago • 4 comments

I've a requestResponseLogger middleware which I'm trying to test few uses

  1. when request is sent, it should log req info (call logger.log)
  2. when response is success, it should log res info. status code, requested endpoint (call logger.log)
  3. when response is errored, it should log res info . status code, requested endpoint (call logger.warn)

here is the sample middleware. How can i create response for success and error scenarios, so I can test the correct logs are being called.


function requestResponseLogger(req, res, next) { 
  logger.info(`Received request: ${req.method} ${req.originalUrl}`);
  var oldWrite = res.write,
      oldEnd = res.end;

  var chunks = [];

  res.write = function (chunk) {

    chunks.push(new Buffer(chunk));
    oldWrite.apply(res, arguments);
  };

  res.end = function (chunk) {

      logger.info(
        `Sent response: ${res.statusCode} ${
          req.originalUrl}`
      );
  
      // logging response body based on condition (removed the code for simplicity)
      oldEnd.apply(res, arguments);
  };

  res.on("error", (err: any) => {

      logger.warn(
        `Error from ${req.method} ${req.originalUrl}: ${JSON.stringify(
          err
        )}`
      );
    });

  next();
}

vejandla avatar Apr 01 '24 20:04 vejandla

Hi @vejandla, to test middleware that relies on events (has res.on()) you need to use real event emitter in the tests. In this section you will find docs on how to do this https://www.npmjs.com/package/node-mocks-http#createresponse

Then, in order to test res.on("error", ...) logic you can simply use res.emit('error', ...) in the tests code.

eugef avatar Apr 02 '24 13:04 eugef

thanks @eugef for the reply.


it(`should log the ougoing response as warning.`, (done) => {
      const req = httpMocks.createRequest({
        originalUrl: "/response-test",
        method: "DELETE",
        body: {
          test: "ERROR-TEST",
        },
      });
      const res = httpMocks.createResponse({
        eventEmitter: require("events").EventEmitters,
      });
      res.statusCode = 500;
      res.setHeader("content-type", "not an Image");
      res.on("error", async () => {
        expect(logger.info).toHaveBeenCalledTimes(1);
        expect(logger.warn).toHaveBeenNthCalledWith(
          1,
          expect.stringContaining(
            `Error from ${req.method} ${req.originalUrl}:`
          )
        );
        done();
      });
      req.send("data sent in request");
      requestResponseLogger(req, res, (() => {}) as NextFunction);
      res.emit("error", "unexpected error occurred");
    });

This is always failing with timeout. Looks like the res.emit is not being caught in the test.

vejandla avatar Apr 02 '24 21:04 vejandla

any help on this issue?

vejandla avatar Apr 20 '24 16:04 vejandla

Stale issue message

github-actions[bot] avatar Jun 20 '24 00:06 github-actions[bot]

Stale issue message

github-actions[bot] avatar Aug 21 '24 01:08 github-actions[bot]