0

I'm using jest on my e-commerce software so I can also do render tests when end-to-end testing (themes are supported, that's why).
But I'm currently just testing some mongoose functionality and when I'm trying to save a document, it gives me this error: Error: Timeout - Async callback was not invoked within the 10000ms timeout specified by jest.setTimeout.

I noticed it doesn't give that error when I remove the lines with await doc.save();. So I think it has something to do with async/await, but I can't find it.

package.json

"jest": {
  "automock": false,
  "moduleDirectories": [
    "node_modules"
  ],
  "testPathIgnorePatterns": [
    "node_modules",
    ".idea",
    "public"
  ],
  "collectCoverage": true,
  "coverageThreshold": {
    "global": {
      "branches": 5,
      "lines": 40,
      "functions": 25,
      "statements": -1000
    }
  },
  "setupTestFrameworkScriptFile": "./setupJest.js",
  "coverageDirectory": "coverage",
  "globalSetup": "./globalSetupJest.js"
}

globalSetupJest.js

const Mongoose = require('mongoose').Mongoose;
const mongoose = new Mongoose();

const Mockgoose = require('mockgoose').Mockgoose;
const mockgoose = new Mockgoose(mongoose);
const {promisify} = require('util');

module.exports = async () => {
    try {

        await mockgoose.prepareStorage();
        promisify(mongoose.connect);

        await mongoose.connect('mongodb://localhost/test')

        mongoose.connection.on('connected', () => {
            console.log('db connection is now open');
        });

    } catch (e) {
        console.log('error in setting up mockgoose', e);
    }
};

Product.test.js

describe('Product', () => {
    const index = require('./index');
    const productSchema = require('./model');

    const Product = mongoose.model(index.modelName, productSchema);

    describe('Instance Functionality', () => {
        let baseProductObj;
        let localProduct;

        beforeEach(async () => {
            baseProductObj = {
                ean: 123456789,
                title: 'Test product',
                description: 'Test description',
                stock: {
                    amount: 5,
                    track: true
                },
                pricing: {
                    cost: 5,
                    price: 10
                },
                url: 'test-product'
            };
            localProduct = new Product(baseProductObj);
            try {
                return await localProduct.save();
            } catch (e) {
                console.log('error in beforeEach', e);
            }
        });

        describe('.reduceStock', () => {
            test('Should decrease the stock by a default of 1', async () => {
                try {
                    localProduct.reduceStock();
                    await localProduct.save();
                } catch (e) {
                    console.log('error in saving localProduct', e);
                }
                expect(localProduct.stock.amount).toEqual(4);
            });
        });
    });
});
CherryNerd
  • 1,258
  • 1
  • 16
  • 38
  • Those try..catch are misleading. You don't need them in tests. A honest rejection is preferable. I don't see why there should be timeout. Possibly a problem with DB connection. – Estus Flask Jul 13 '18 at 21:35

2 Answers2

0

I've not used JEST for some time but I think you need "done" callback for asynchronous code.

Your code should be:

test("Should decrease the stock by a default of 1", async (done) => {
  try {
    localProduct.reduceStock();
    await localProduct.save();
    done();
  } catch (e) {
    console.log("error in saving localProduct", e);
  }
  expect(localProduct.stock.amount).toEqual(4);
});

If that does not work, try to return the document.

await localProduct.save();

should be

return await localProduct.save();
Faheem
  • 1,105
  • 11
  • 28
-1

You can specify a larger timeout inside the test by adding:

jest.setTimeout(50000);
Tiago Martins Peres
  • 14,289
  • 18
  • 86
  • 145