6

I'm running unittests via Mocha / Chai on a sequelize definition as shown:

Main tests.js that is run with mocha tests.js:

// Testing Dependencies
expect = require("chai").expect;
should = require("chai").should;
require('dotenv').load();

var Sequelize = require('sequelize');
var sequelize = new Sequelize(
    process.env.PG_DB_TEST,
    process.env.PG_USER,
    process.env.PG_PASSWORD, {
    dialect: "postgres",
    logging: false
});

var models = require('./models/db')(sequelize);

var seq_test = function (next) {
  return function () {
    beforeEach(function (done) {
        sequelize.sync({ force: true }).then(function() {
            done();
        });
    });

    afterEach(function (done) {
        sequelize.drop().then(function() {
            done();
        });
    });

    next();
  };
}

describe("Model Unittests", seq_test(function () {
  require("./models/tests/test_user.js")(models);
  require("./models/tests/test_interest.js")(models);
}));

test_user.js

var mockedUser = require("./mocks/user");

module.exports = function (models) {
  var User = models.user;
  it("User should have the correct fields", function (done) {
    User.create(mockedUser).then(function (result) {
      expect(result.pack()).to.include.all.keys(
            ["id", "name", "email", "intro"]
      );
      done();
    });
  });

  it("User should require an email", function (done) {
    User.create({
      "name": mockedUser['name']
    }).then(function (result) {
      expect.fail();
      done();
    }).catch(function (err) {
      expect(err['name']).to.be.equal('SequelizeValidationError');
      done();
    });
  });

  it("User should require a name", function (done) {
    User.create({
      "email": mockedUser['email']
    }).then(function (result) {
      expect.fail();
      done();
    }).catch(function (err) {
      expect(err['name']).to.be.equal('SequelizeValidationError');
      done();
    });
  });
}

Sometimes (about 1 out of 15 on a Codeship (CI)), it gives this error:

  Model Unittests
Unhandled rejection SequelizeUniqueConstraintError: Validation error
at Query.formatError (/home/rof/src/github.com/podtogether/pod-test-prototype/node_modules/sequelize/lib/dialects/postgres/query.js:402:16)
at null.<anonymous> (/home/rof/src/github.com/podtogether/pod-test-prototype/node_modules/sequelize/lib/dialects/postgres/query.js:108:19)
at emitOne (events.js:77:13)
at emit (events.js:169:7)
at Query.handleError (/home/rof/src/github.com/podtogether/pod-test-prototype/node_modules/pg/lib/query.js:108:8)
at null.<anonymous> (/home/rof/src/github.com/podtogether/pod-test-prototype/node_modules/pg/lib/client.js:171:26)
at emitOne (events.js:77:13)
at emit (events.js:169:7)
at Socket.<anonymous> (/home/rof/src/github.com/podtogether/pod-test-prototype/node_modules/pg/lib/connection.js:109:12)
at emitOne (events.js:77:13)
at Socket.emit (events.js:169:7)
at readableAddChunk (_stream_readable.js:146:16)
at Socket.Readable.push (_stream_readable.js:110:10)
at TCP.onread (net.js:523:20)
  1) "before each" hook for "User should have the correct fields"

Locally, these unittests haven't failed (I've run it perhaps... 60 times in a row). I saw similar issues earlier when I didn't use the done callback in the beforeEach and afterEach. Both of those were async and needed to wait before continuing. After fixing that, I stopped seeing these issues locally.

Can anyone shed some light on this issue? (ssh'ed into Codeship and ran the tests resulted in the 1 / ~15 error)

sihrc
  • 2,728
  • 2
  • 22
  • 43
  • Did you ever figure this out? Our unit tests fail because of this probably no less than 20% of the time. – smalone Oct 15 '15 at 01:41
  • No, unfortunately I haven't. I'd guess its some kind of async behavior that's not handled correctly yet? Not sure why it works on my local machine perfectly though. – sihrc Oct 15 '15 at 19:24
  • 1
    That's ok. I figured out our problem. We were generating random phone numbers for our unit tests. They weren't be removed after the test, so the error was a primary key constraint error. Thanks anyways! I hope you figure out your issue. – smalone Oct 21 '15 at 16:15

2 Answers2

2

I had this issue with my QA database. Sometimes a new record would save to the database, and sometimes it would fail. When performing the same process on my dev workstation it would succeed every time.

When I caught the error and printed the full results to the console, it confirmed that a unique constraint as being violated - specifically, the primary key id column, which was set to default to an autoincremented value.

I had seeded my database with records, and even though the ids of those records were also set to autoincrement, the ids of the 200-some records were scattered between 1 and 2000, but the database's autoincrement sequence was set to start at 1. Usually the next id in sequence was unused, but occasionally it was already occupied, and the database would return this error.

I used the answer here to reset the sequence to start after the last of my seeded records, and now it works every time.

If you are seeding records to run integration tests on, it is possible that the database autoincrement sequence isn't set to follow them. Sequelize doesn't have this functionality because it's a simple, single command operation that needs to be run in the database.

aherocalledFrog
  • 831
  • 9
  • 13
2

I had this issue. It was caused by the autoincrement not being set correctly after seeding. The root issue was that our seed methods were explicitly setting the primary/autoincremented key (id) in the seed method, which should generally be avoided. We remove the ids, and the issue was resolved.

Here's a reference to the sequelize issue where we found the solution: https://github.com/sequelize/sequelize/issues/9295#issuecomment-382570944