1

I am trying to run Jest API tests using SuperTest. I'm using MongoDB 4.2 with transactions. When I run Jest, MongoDB throws an error. Please see below.

db.js

const mongoose = require('mongoose');

async function connect() {
    mongoose.connect(global.__MONGO_URI__, {
        useNewUrlParser: true,
        useUnifiedTopology: true,
        useCreateIndex: true,
        useFindAndModify: false,
    });
}

async function disconnect() {
    await mongoose.connection.dropDatabase();
    await mongoose.connection.close();
}

module.exports = {
    connect,
    disconnect,
}

server.js

const express = require('express');
const app = express();
const logger = require('./services/logger');
const port = process.env.PORT || 3000;

// get all routes
require('./routing')(app);

app.listen(port, () => logger.info(`App is listening on port ${port}!`));

module.exports = app

jest.config.js

module.exports = {
    coveragePathIgnorePatterns: ['/node_modules/'],
    preset: '@shelf/jest-mongodb',
    verbose: true,
}

user.test.js

const request = require("supertest");
const faker = require('faker');
const db = require('../db')
const app = require('../../server');


describe('user routes', () => {
    beforeAll(async () => await db.connect());
    afterAll(async () => await db.disconnect());

    it('should register new user', done => {
        const password = faker.internet.password();
        request(app)
            .post('/v1/users/register')
            .send({
                firstName: faker.name.firstName(),
                lastName: faker.name.lastName(),
                email: faker.internet.email(),
                password,
                confirmPassword: password,
                termsConditions: true,
            })
            .expect(200, done);
    });
});

Here is the error I received in the console.

    > jest

(node:10487) [MDEP001] DeprecationWarning: "MongoMemoryReplSet.getConnectionString" is deprecated, use ".getUri"
(Use `node --trace-deprecation ...` to show where the warning was created)
info:   App is listening on port 3000!
 FAIL  __test__/routes/users.test.js
  user routes
    ✕ should register new user (153 ms)

  ● user routes › should register new user

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

      21 |                 termsConditions: true,
      22 |             })
    > 23 |             .expect(200, done);            
         |              ^
      24 |     });
      25 | });

      at Object.<anonymous> (__test__/routes/users.test.js:23:14)
      ----
      at Test.Object.<anonymous>.Test._assertStatus (node_modules/supertest/lib/test.js:296:12)
      at node_modules/supertest/lib/test.js:80:15
      at Test.Object.<anonymous>.Test._assertFunction (node_modules/supertest/lib/test.js:311:11)
      at Test.Object.<anonymous>.Test.assert (node_modules/supertest/lib/test.js:201:21)
      at Server.localAssert (node_modules/supertest/lib/test.js:159:12)

Test Suites: 1 failed, 1 total
Tests:       1 failed, 1 total
Snapshots:   0 total
Time:        1.976 s, estimated 2 s
Ran all test suites.
error:  MongoError: This MongoDB deployment does not support retryable writes. Please add retryWrites=false to your connection string.
    at getMMAPError (/home/yehuda_fievel/repos/books/server/node_modules/mongodb/lib/core/topologies/shared.js:413:18)
    at handler (/home/yehuda_fievel/repos/books/server/node_modules/mongodb/lib/core/sdam/topology.js:946:15)
    at /home/yehuda_fievel/repos/books/server/node_modules/mongodb/lib/cmap/connection_pool.js:348:13
    at handleOperationResult (/home/yehuda_fievel/repos/books/server/node_modules/mongodb/lib/core/sdam/server.js:558:5)
    at commandResponseHandler (/home/yehuda_fievel/repos/books/server/node_modules/mongodb/lib/core/wireprotocol/command.js:115:25)
    at MessageStream.messageHandler (/home/yehuda_fievel/repos/books/server/node_modules/mongodb/lib/cmap/connection.js:268:11)
    at MessageStream.emit (events.js:315:20)
    at processIncomingData (/home/yehuda_fievel/repos/books/server/node_modules/mongodb/lib/cmap/message_stream.js:144:12)
    at MessageStream._write (/home/yehuda_fievel/repos/books/server/node_modules/mongodb/lib/cmap/message_stream.js:42:5)
    at writeOrBuffer (internal/streams/writable.js:358:12)
    at MessageStream.Writable.write (internal/streams/writable.js:303:10)
    at Socket.ondata (internal/streams/readable.js:719:22)
    at Socket.emit (events.js:315:20)
    at addChunk (internal/streams/readable.js:309:12)
    at readableAddChunk (internal/streams/readable.js:284:9)
    at Socket.Readable.push (internal/streams/readable.js:223:10)
Jest did not exit one second after the test run has completed.

This usually means that there are asynchronous operations that weren't stopped in your tests. Consider running Jest with `--detectOpenHandles` to troubleshoot this issue.

I tried their suggestion to add retryWrites=false to the Mongoose connect options but that didn't help.

Any help would be appreciated. Thanks.

Yehuda_Fievel
  • 111
  • 2
  • 9
  • I think you did not separate the app and app.listen. check this accpted answer : https://stackoverflow.com/questions/56122778/supertest-not-found-error-testing-express-endpoint/57368925#57368925 – Yilmaz Apr 27 '21 at 10:37
  • I tried what you said and still got the same error. I tried creating a user without the transaction (after making your suggestion) and it worked. This leads me to assume there is a problem with the jest mongodb package that it cannot handle transactions. – Yehuda_Fievel Apr 28 '21 at 13:09

1 Answers1

0

I just checked on the github account of @shelf/jest-mongodb and they don't support replica set for transactions. See below.

https://github.com/shelfio/jest-mongodb/issues/152

Yehuda_Fievel
  • 111
  • 2
  • 9