Ad

How To Test A "throwing An Error" In Mocha Having It In Asyncronous Code (read From Db) Using Only Callbacks (no Promises, Async/await)?

- 1 answer

I want to write some tests for a method which reads from a JSON file (simulating a db) and returns the correct name, given that exists.

This is the code I have written for my method. It does throw an error when the id is not valid.

const getOne = (id, callback) => {
    ...
    fs.readFile('db.json', (err, data) => {
      if (err) {
        throw new Error('Error reading file');
      }
      const person = JSON.parse(data)
        .filter(el => el.id === id)
        .map(el => el.name);
      if (person.length === 0) {
        throw new Error('It does not match DB entry');
      }
      callback(person);
    });
    ...

The test I have written is:

it('Should reject an invalid id', (done) => {

    api.getOne(100, (person) => {
      try {
        personFromDB = person;
      } catch (error) {

        assert.throws(() => {  
          }, new Error('It does not match DB entry'));
          //done();
      }

But it doesn't seem to pass the test. When I have the 'done()' uncommented, it passes the test, but I don't think it is because I pass the actual test, but rather because the test gets in the catch and executes the done() callback.

Any help, guidance or recommendation is much appreciated.

Ad

Answer

You won't be able to catch an Error being thrown in the fs.readFile callback.

Instead, pass any errors to the callback you pass to getOne.

Then you can check if an Error got passed to your callback in your test.

Here is a working example to get you started:

const fs = require('fs');
const assert = require('assert');

const api = {
  getOne: (id, callback) => {
    // ...
    fs.readFile('db.json', (err, data) => {
      if (err) return callback(err);  // <= pass err to your callback
      const person = JSON.parse(data)
        .filter(el => el.id === id)
        .map(el => el.name);
      if (person.length === 0) return callback(new Error('It does not match DB entry'));  // <= pass the Error to your callback
      callback(null, person);  // <= call the callback with person if everything worked
    })
  }
}

it('Should reject an invalid id', done => {
  api.getOne(100, (err, person) => {
    assert.strictEqual(err.message, 'It does not match DB entry');  // Success!
    done();
  });
});
Ad
source: stackoverflow.com
Ad