Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

expectBody not verbose enough #16

Open
mgcrea opened this issue Oct 12, 2018 · 6 comments
Open

expectBody not verbose enough #16

mgcrea opened this issue Oct 12, 2018 · 6 comments

Comments

@mgcrea
Copy link

mgcrea commented Oct 12, 2018

When reading the docs, we could expect:

  it('should return a response', async () => {
    await fetch('/hello')
      .expect(200)
      .expect('content-type', /^application\/json/)
      .expect({greeting: 'Hello!'});
  });

to have the same behavior than:

  it('should return a response', async () => {
    const response = await fetch('/hello')
      .expect(200)
      .expect('content-type', /^application\/json/);
    expect(await response.json()).toEqual({greeting: 'Hello!'});
  });

However these two examples give very different outputs:

    AssertionError [ERR_ASSERTION]: Request "GET /me" should have expected JSON body

vs.

    expect(received).toEqual(expected)

    Expected value to equal:
      {"greeting": "Hello!"}
    Received:
      {"foo": "bar"}

    Difference:

    - Expected
    + Received

      Object {
    -   "greeting": "Hello!",
    +   "foo": "bar",
      }

Not sure if this is easily doable but having the actual expect error thrown in the first case would be great as it's quite impractical for now.

Thanks for the great lib!


EDIT I realized that this was due to the fact that I'm using jest version of expect. Since the package is quite small, I think it would be great to rely on it to test assertions. As you'll get nice diffed output.

@jwalton
Copy link
Owner

jwalton commented Oct 12, 2018

I just tried cloning a fresh copy

$ git clone git@github.com:jwalton/node-supertest-fetch.git
$ cd node-supertest-fetch
$ npm install

And then I added this to test/test.ts:

    it('should generate a nice diff if body is incorrect', async function() {
        await fetch(this.server, '/hello')
                .expectStatus(200)
                .expectHeader('content-type', 'application/json')
                .expectBody({greeting: "Hello2!"});
    });

And when I npm test, I get back:

  1) supertest-fetch
       should generate a nice diff if body is incorrect:

      AssertionError [ERR_ASSERTION]: Request "GET /hello" should have expected JSON body
      + expected - actual

       {
      -  "greeting": "Hello!"
      +  "greeting": "Hello2!"
       }

supertest-fetch is just using straight up assert, which is also what chai is based on. If you try something like this in the REPL:

> assert = require('assert');
> let err;
> try { assert.deepStrictEqual({a: "foo"}, {a: "bar"}) } catch(e) { err = e; }

And then have a look at err, it has an actual and an expected field, which is what your test runner (in my case, mocha) should be using to generate that nice looking diff.

So, I guess the first question is, what test runner are you using? I guess Jest? I've never used it, but at a glance Jest is supposed to handle this.

@mgcrea
Copy link
Author

mgcrea commented Oct 15, 2018

Indeed I'm using jest and I'm not getting a smart output. Tried with your project using jest + ts-jest:

yarn add --dev jest
yarn add --dev ts-jest

With the following jest.config.js file:

module.exports = {
  preset: 'ts-jest',
  testEnvironment: 'node',
  testMatch: ['**/?(*.)+(spec|test).(j|t)s?(x)'],
  setupFiles: ['<rootDir>/test/setup.js']
};

With this test/setup.js file:

global.fetch = require('node-fetch');

And the following test/test.spec.ts:

import http from 'http';
import { fetch } from '../../src';

const server = http.createServer(
    (req, res) => {
        if(req.url === '/hello') {
            res.setHeader('content-type', 'application/json');
            res.end(JSON.stringify({greeting: "Hello!"}));
        } else if(req.url === '/hellotext') {
            res.end("Hello");
        } else if(req.url === '/err') {
            res.setHeader('content-type', req.headers['content-type'] || 'text/plain');
            res.statusCode = 400;
            res.end('Boom!\nLong message\n');
        } else {
            res.statusCode = 404;
            res.end();
        }
    }
);


it('should generate a nice diff if body is incorrect', async function() {
    await fetch(server, '/hello')
        .expectStatus(200)
        .expectHeader('content-type', 'application/json')
        .expectBody({greeting: "Hello2!"});
});

Running with yarn jest test/test.spec.ts won't give you a nice diff.

@jwalton
Copy link
Owner

jwalton commented Oct 15, 2018

If you want another quick test, try writing a jest test that just does something like:

assert.deepStrictEqual({a: "foo"}, {a: "bar"});

and see what that does. If that doesn't produce a pretty diff for you, I'd suggest this is something you should raise with the jest project.

@mgcrea
Copy link
Author

mgcrea commented Oct 15, 2018

Does seem to work fine with jest, in another project:

  it.only('test', () => {
    require('assert').deepStrictEqual({a: 'foo'}, {a: 'bar'});
  });

Gives me:

    assert.deepStrictEqual(received, expected)

    Expected value to deeply and strictly equal to:
      {"a": "bar"}
    Received:
      {"a": "foo"}

    Difference:

    - Expected
    + Received

      Object {
    -   "a": "bar",
    +   "a": "foo",
      }

@jwalton
Copy link
Owner

jwalton commented Oct 15, 2018

I believe the technical term I'm looking for is "wat!?"

This is exactly what we're doing in supertest-fetch. -_-

@mgcrea
Copy link
Author

mgcrea commented Oct 15, 2018

I'm playing with the source to see if I can pinpoint the diff, very strange indeed:

$ /private/tmp/node-supertest-fetch/node_modules/.bin/jest test/spec/test.spec.ts
 FAIL  test/spec/test.spec.ts
  ✕ test (11ms)
  ✕ should generate a nice diff if body is incorrect (26ms)

  ● test

    assert.deepStrictEqual(received, expected)

    Expected value to deeply and strictly equal to:
      {"a": "bar"}
    Received:
      {"a": "foo"}

    Difference:

    - Expected
    + Received

      Object {
    -   "a": "bar",
    +   "a": "foo",
      }

      21 | 
      22 | it('test', () => {
    > 23 |     require('assert').deepStrictEqual({a: 'foo'}, {a: 'bar'});
         |                       ^
      24 | });
      25 | 
      26 | it('should generate a nice diff if body is incorrect', async function() {

      at Object.<anonymous> (test/spec/test.spec.ts:23:23)

  ● should generate a nice diff if body is incorrect

    AssertionError [ERR_ASSERTION]: { greeting: 'Hello!' } deepStrictEqual { greeting: 'Hello2!' }

      183 |                     });
      184 |                 }
    > 185 |                 assert.deepStrictEqual(
          |                        ^
      186 |                     jsonBody,
      187 |                     expectedBody
      188 |                 );

      at Test.<anonymous> (src/Test.ts:185:24)
      at step (src/Test.ts:32:23)
      at Object.next (src/Test.ts:13:53)
      at fulfilled (src/Test.ts:4:58)

EDIT the Jest error formatter is here: https://github.com/facebook/jest/blob/master/packages/jest-circus/src/format_node_assert_errors.js

Can't really find what might be going on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants