supertest icon indicating copy to clipboard operation
supertest copied to clipboard

Supertest should report response body on error

Open phil294 opened this issue 5 years ago • 2 comments

Since #95 got closed 6 years ago and there seems to be no incentive to reopen this, here's an almost 1:1 copy of that issue, but instead of reporting the hard coded .error property, imo the entire response body should be printed out, as currently the server response is disregarded completely.


At the moment when the status message does not match the expectations we get an error message like: expected 200 "OK, got 500 Internal server error It would be helpful to display a server custom error message if any, as defined by: res.send(500, { error: 'something blew up' }); would display: expected 200 "OK", got 500 with response "{ error: 'something blew up' }"


+1, but maybe we should just add the contents of res.body. It should contain the relevant error messages that would help devs figure out what the errors are.

phil294 avatar Feb 25 '20 18:02 phil294

+1, found myself wishing for this today.

nickbclifford avatar Mar 28 '20 19:03 nickbclifford

It's a bit complex, but I've worked around this by defining a custom jest matcher

expect.extend({
  toBeOk(response: Response) {
    if (response.ok) {
      return {
        message: () => 'Ok',
        pass: true,
      };
    } else {
      return {
        message: () => {
          const request = response.request;
          // Format the request and response as CURL output for debugging.
          return [
            `> ${request.method} ${request.url} HTTP/1.1`,
            formatHeaders('> ', request.headers),
            `< HTTP/1.1 ${response.status}`,
            formatHeaders('< ', response.headers),
            response.text,
          ]
            .filter(Boolean)
            .join('\n');
        },
        pass: false,
      };
    }
  },
});
function formatHeaders(
  prefix: string,
  headers: Response['headers'] | Response['request']['headers'] | undefined | null,
) {
  if (!headers) return undefined;
  const entries =
    headers instanceof Headers ? Array.from(headers.entries()) : Object.entries(headers);
  entries.map(([key, value]) => `${prefix}${key}: ${value}`).join('\n');
}

and corresponding jest.d.ts

declare global {
  namespace jest {
    interface Matchers<R> {
      toBeOk(): R;
    }
  }
}
export {};

It can be used as

expect(response).toBeOk();

lucaswoj avatar Feb 09 '24 20:02 lucaswoj