Search code examples
javascriptpromisemocha.jsnode-assert

Mocha / Node: how to use assert.rejects()?


I tried to followed the documentation in order to test for the error message using assert.rejects (I do have Node above v10).

But it's always passing, even with a ridiculous message. What am I doing wrong?

it("should fail but it's not", 
  async ()=> {
    let itemId = 'not an id'
    assert.rejects( 
      await ListRepo.checkById(itemId),
      {message: 'abracadabra'}                        
    )
  }
)

UPDATE: It seems that if I return the assert.rejects, it works. But I still don't know the reason.


Solution

  • As I write this, everything written above/previously is correct, but much of it is needlessly complicated. It is correct that you must return a promise, so that mocha itself has something to wait for, otherwise it returns immediately (before your promise can resolve or reject). The missing piece is that manually waiting for a promise is rarely what you actually want to do here.

    This simplest pattern is hinted at by @caub in a comment--await the promise returned by assert.rejects. Specifically:

    it("should fail but it's not", 
      async ()=> {
        let itemId = 'not an id'
        await assert.rejects( 
          ListRepo.checkById(itemId),
          {message: 'abracadabra'}                        
        )
      }
    )
    

    There are three key things here:

    1. The test function itself must be async.
    2. await the assert.rejects call inside the (async) test function. This automatically makes the test function return Promise<void>, which is exactly what you want. This puts the important part right at the point of the assert call, and compared to manually returning/handling a promise, makes it easier to copy/paste the call elsewhere and makes it easier to assert multiple rejections in one test.
    3. Do not await what you're passing into the rejects call. You should be passing in a promise--not an awaited value.