eugef / node-mocks-http

Mock 'http' objects for testing Express,js, Next.js and Koa routing functions
Other
755 stars 134 forks source link

how to create error response? #297

Closed vejandla closed 1 month ago

vejandla commented 6 months ago

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();
}
eugef commented 6 months ago

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.

vejandla commented 6 months ago

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 commented 5 months ago

any help on this issue?

github-actions[bot] commented 3 months ago

Stale issue message

github-actions[bot] commented 1 month ago

Stale issue message