Skip to content

Instantly share code, notes, and snippets.

@nilscox
Last active February 4, 2022 19:32
Show Gist options
  • Select an option

  • Save nilscox/2811e88c8fd78ea7e42175c73b66b2d0 to your computer and use it in GitHub Desktop.

Select an option

Save nilscox/2811e88c8fd78ea7e42175c73b66b2d0 to your computer and use it in GitHub Desktop.
const stringifyRequest = (request) => {
const { req, res, _data } = request;
const requestStr = [
...req._header.split('\r\n').slice(0, -1),
...JSON.stringify(_data).split('\n'),
].map(line => '> ' + line).join('\r\n');
const responseStr = [
[res.statusCode, res.statusMessage, res.httpVersion].join(' '),
...Object.entries(res.headers).map(([key, value]) => [key, value].join(': ')),
'',
res.text,
].map(line => '< ' + line).join('\r\n');
return [requestStr, responseStr];
}
const plugin = (request) => {
const _assertStatus = request._assertStatus.bind(request);
request._assertStatus = (status, res) => {
const result = _assertStatus(status, res);
if (result instanceof Error) {
const [requestStr, responseStr] = stringifyRequest(request);
return new Error([result.message, requestStr, responseStr].join('\n\n'));
}
return result;
};
};
module.exports = plugin;

This is a supertest plugin, that will log the raw request and response when an assertion fails.

For now, it only handles supertest's .status() assertion, but I will most likely support other assertions later.

Usage:

app.js

const express = require('express');
const bodyParser = require('body-parser');

const app = express();

app.use(bodyParser.json());

app.post('/login', (req, res) => {
  const { body } = req;

  if (!body.username)
    return res.status(400).json({ error: 'missing username' });

  if (!body.password)
    return res.status(400).json({ error: 'missing password' });

  if (body.username === 'hello' && body.password === 'world')
    return res.status(200).end();

  res.status(401).end();
});

module.exports = app;

app.spec.js

const supertest = require('supertest');

const debug = require('./supertest-debug-plugin');
const app = require('./app');

describe('login', () => {
  const agent = supertest.agent(app);

  agent.use(debug);
  
  it('should login', async () => {
    await agent
      .post('/login')
      .send({ usernme: 'hello', password: 'world' })
      .expect(200);
  });
});

Output:

$ jest
 FAIL  src/app.spec.js
  login
    ✕ should login (22 ms)

  ● login › should login

    expected 200 "OK", got 400 "Bad Request"

    > POST /login HTTP/1.1
    > Host: 127.0.0.1:39435
    > Accept-Encoding: gzip, deflate
    > User-Agent: node-superagent/3.8.3
    > Content-Type: application/json
    > Content-Length: 38
    > Connection: close
    > 
    > {"usernme":"hello","password":"world"}

    < 400 Bad Request 1.1
    < x-powered-by: Express
    < content-type: application/json; charset=utf-8
    < content-length: 28
    < etag: W/"1c-FCD+Zp3vrrVF7rKFRBUffr4IZlw"
    < date: Sat, 19 Sep 2020 15:10:49 GMT
    < connection: close
    < 
    < {"error":"missing username"}
@nilscox
Copy link
Author

nilscox commented Feb 4, 2022

Sometimes I also simply use this

import { Request } from 'supertest';

export const logResponse = (req: Request) => {
  req.on('response', (res) => console.log(res.body));
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment