How To Test A "throwing An Error" In Mocha Having It In Asyncronous Code (read From Db) Using Only Callbacks (no Promises, Async/await)?
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.
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();
});
});
Related Questions
- → How to update data attribute on Ajax complete
- → October CMS - Radio Button Ajax Click Twice in a Row Causes Content to disappear
- → Octobercms Component Unique id (Twig & Javascript)
- → Passing a JS var from AJAX response to Twig
- → Laravel {!! Form::open() !!} doesn't work within AngularJS
- → DropzoneJS & Laravel - Output form validation errors
- → Import statement and Babel
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM