ladjs / supertest

🕷 Super-agent driven library for testing node.js HTTP servers using a fluent API. Maintained for @forwardemail, @ladjs, @spamscanner, @breejs, @cabinjs, and @lassjs.
MIT License
13.75k stars 758 forks source link

Supertest should report response body on error #631

Open phil294 opened 4 years ago

phil294 commented 4 years ago

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.

nickbclifford commented 4 years ago

+1, found myself wishing for this today.

lucaswoj commented 7 months ago

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();