I am writing some mocha tests where I initialize the postgress DB using knex in the beaforeEach(), afterEach() and after() hooks.

Here is an example test:

const chai = require('chai');
const should = chai.should();

const knex = require('../../src/server/db/connection').knex;

describe('test01', function() {

  beforeEach( async function() {
    try {
      await knex.migrate.rollback();
      //await knex.migrate.latest();
    } catch (err) {
      throw err;
    }
  });

  afterEach(async function() {
    try {
      await knex.migrate.rollback();
    } catch (err) {
      throw err;
    }
  });

  after(async function() {
    try {
      await knex.destroy();
    } catch (err) {
      console.log(err);
      throw err;
    }
  });

  describe.only('check array', function() {
    it('responds with matching records', async function() {
      const users = [1, 2, 3, 4];
      users.should.have.length(3);
    });
  });
});

If I run the test like written above it performs as expected. It fails and prints the expected message:

  test
    1) check arrays


  0 passing (167ms)
  1 failing

  1) test
       check arrays:

      AssertionError: expected [ 1, 2, 3, 4 ] to have a length of 3 but got 4
      + expected - actual

      -4
      +3

      at Context.<anonymous> (test\unit\auth.test.js:120:23)

But if I try to execute the migrations uncommeting the await knex.migrate.latest() line the test fails in the after() hook and prints no error message. The output is just this:

  test
    1) check arrays


  0 passing (838ms)
  1 failing

  2) "after all" hook

Some important details:

  • I am on Windows 10
  • knex migrations definitely work, I can see the tables been created and dropped correctly.
  • I have tried to place some traces but no error is ever catched. Al hooks complete correctly.
  • I have tried running the same code in Linux using Docker but result is exactly the same
  • I have tried using the .then()/done() style instead of the async/await and result is identical.

Here is my package.json:

{
  "engines": {
    "node": "10.7.0",
    "npm": "6.2.0"
  },},
  "dependencies": {
    "bcryptjs": "2.4.0",
    "body-parser": "1.17.2",
    "bookshelf": "0.14.2",
    "bookshelf-modelbase": "2.10.4",
    "cloudinary": "1.9.0",
    "dateformat": "2.0.0",
    "debug": "2.2.0",
    "dotenv": "4.0.0",
    "express": "4.13.4",
    "express-jwt": "5.3.0",
    "expressive-hrbac": "^1.0.1",
    "fs-extra": "4.0.0",
    "joi": "13.4.0",
    "jsend": "1.0.2",
    "jsonwebtoken": "7.4.1",
    "knex": "0.16.3",
    "morgan": "1.7.0",
    "multer": "1.3.0",
    "nunjucks": "2.4.2",
    "passport": "0.3.2",
    "passport-local": "1.0.0",
    "passport-stub": "1.1.1",
    "pg": "7.4.3",
  },
  "devDependencies": {
    "chai": "4.2.0",
    "chai-as-promised": "7.1.1",
    "chai-http": "4.2.1",
    "chai-jwt": "2.0.0",
    "console.table": "^0.10.0",
    "eslint": "5.2.0",
    "gulp": "3.9.1",
    "gulp-eslint": "4.0.0",
    "gulp-jscs": "4.0.0",
    "gulp-jshint": "2.0.1",
    "gulp-nodemon": "2.1.0",
    "gulp-plumber": "1.1.0",
    "jshint": "2.9.3",
    "jshint-stylish": "2.2.1",
    "jwt-simple": "0.5.5",
    "minimist": "^1.2.0",
    "mocha": "5.2.0",
    "mocha-eslint": "5.0.0",
    "mocha-jscs": "5.0.1",
    "mocha-jshint": "2.3.1",
    "pg-format": "^1.0.4",
    "run-sequence": "1.2.2",
    "shelljs": "0.8.1",
    "tiny-lr": "0.2.1"
  },
}

Thanks

EDIT 13 Apr 2019

After some debugging I have realized that the problem is in the mocha reporter processing of the stack trace produced by the chai checks. Mocha is assuming that the error.stack is a string and in lib/reporters/base.js tries to split it with:

    // indent stack trace
    stack = stack.replace(/^/gm, '  ');

Without the await knex.migrate.latest() line that works because the stack is indeed a string. It looks like so:

    at chai.request.post.end (test\integration\routes.user.test.js:152:27)
    at Test.Request.callback (node_modules\superagent\lib\node\index.js:716:12)
    at parser (node_modules\superagent\lib\node\index.js:916:18)
    at IncomingMessage.res.on (node_modules\superagent\lib\node\parsers\json.js:19:7)
    at endReadableNT (_stream_readable.js:1132:12)
    at processTicksAndRejections (internal/process/next_tick.js:76:17)

When the await knex.migrate.latest() line is uncommented the stack changes into an array and looks like this:

[ CallSite {},
  CallSite {},
  CallSite {},
  CallSite {},
  CallSite {},
  CallSite {},
  CallSite {} ]

the replace() method throws an exception causing the problem. I suppose with later version of mocha there is a similar processing of the stack causing the problem

0 Answers