Home > Software design >  Expect throw in an async function that calls mongoose with Jest
Expect throw in an async function that calls mongoose with Jest

Time:07-20

I am trying to test my Node.js application with Jest, expecting to receive some errors when I try to save to MongoDB some documents that shouldn't be allowed.

So basically I have this model defined with mongoose:

const UserSchema = new mongoose.Schema({
    email: {
        type: String,
        required: true,
        unique: true,
    },
    password: {
        type: String,
        validate: [ {validator: validatePassword, msg: 'Not good' } ],
    },
});
const User = mongoose.model('User', UserSchema);
module.exports = User;

And then I created a function in my service to create a user. This is the function I am trying to test:

module.exports.save = async function(userData){
    return await User.create(userData);
}

And now I am trying to test this function with Jest. For example I have this:

it('Can be created', async() => {                                                            
    expect(async () => {                                                                 
        await userRepo.save(userComplete);                                           
    }).not.toThrow();                                                                      
});

where userComplete has all the needed arguments. This test works correctly.

Then I create another test:

it('Wrong password', async() => {                                                            
    await expect(userRepo.save(userWrongPassword)).rejects.toThrow(mongoose.Error.ValidationError);
});

Where userWrongPassword has a correct email but a non-allowed password. This test also passes correctly, but now I created a new test, to check we can't add twice the same user:

it('Same email', async() => {                                                                
    expect(async () => {                                                                 
        await userRepo.save(userComplete); 
    }).not.toThrow();                                                                    
                                                                                                     
    await expect(userRepo.save(userUniqueEmail)).rejects.toThrow("E11000 duplicate key error collection: test.users index: email_1 dup key: { email: \"[email protected]\" }");
});

And I am getting this error in the test:

  ● user › Same email

    MongoServerError: E11000 duplicate key error collection: test.users index: email_1 dup key: { email: "[email protected]" }

      at node_modules/mongodb/src/operations/insert.ts:85:25
      at node_modules/mongodb/src/cmap/connection_pool.ts:489:13
      at node_modules/mongodb/src/sdam/server.ts:370:13
      at handleOperationResult (node_modules/mongodb/src/sdam/server.ts:541:14)
      at Connection.onMessage (node_modules/mongodb/src/cmap/connection.ts:462:5)
      at MessageStream.<anonymous> (node_modules/mongodb/src/cmap/connection.ts:268:56)
      at processIncomingData (node_modules/mongodb/src/cmap/message_stream.ts:194:14)
      at MessageStream._write (node_modules/mongodb/src/cmap/message_stream.ts:71:5)

For some reason, this error is not being caught by Jest. Even if I just check rejects.toThrow(Error).

But if I for example set another text in the call:

await expect(userRepo.save(userUniqueEmail)).rejects.toThrow("Hello this is a dummy text"); I also get the previous error, plus a new one:

  ● user › Same email

    expect(received).rejects.toThrow(expected)

    Expected substring: "Hello this is a dummy text"
    Received message:   "E11000 duplicate key error collection: test.users index: email_1 dup key: { email: \"[email protected]\" }"

          at node_modules/mongodb/src/operations/insert.ts:85:25
          at node_modules/mongodb/src/cmap/connection_pool.ts:489:13
          at node_modules/mongodb/src/sdam/server.ts:370:13
          at handleOperationResult (node_modules/mongodb/src/sdam/server.ts:541:14)
          at Connection.onMessage (node_modules/mongodb/src/cmap/connection.ts:462:5)
          at MessageStream.<anonymous> (node_modules/mongodb/src/cmap/connection.ts:268:56)
          at processIncomingData (node_modules/mongodb/src/cmap/message_stream.ts:194:14)
          at MessageStream._write (node_modules/mongodb/src/cmap/message_stream.ts:71:5)

      26 |
      27 |      //await expect(userRepo.save(userUniqueEmail)).rejects.toThrow("E11000 duplicate key error collection: test.users index: email_1 dup key: { email: \"[email protected]\" }");
    > 28 |      await expect(userRepo.save(userUniqueEmail)).rejects.toThrow("Hello this is a dummy text");
         |                                                           ^
      29 |  });
      30 |
      31 |  it('Wrong password', async() => {

      at Object.toThrow (node_modules/expect/build/index.js:241:22)
      at Object.toThrow (tests/userCreate.test.js:28:56)

How can I check that I am throwing a MongoServerError with that specific error message? Why is the MongoServerError not being caught by Jest?

CodePudding user response:

Could it be that you are getting that error from another test :

  expect(async () => {                                                                 
        await userRepo.save(userComplete); 
    }).not.toThrow();   

or

it('Wrong password', async() => {                                                            
    await expect(userRepo.save(userWrongPassword)).rejects.toThrow(mongoose.Error.ValidationError);
});
  • Related