简体   繁体   中英

Testing node.js with mocha and chai

I've been successfully testing my API endpoint built with node.js but still can't figure out how to test this kind of "non async" code.

/**
 * Database service
 */
// Dependencies
const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(module.filename);
let db = {};

// Connection
let sequelize = new Sequelize(process.env.DATABASE_URL, {logging: false});

// Models processing
fs
    .readdirSync(__dirname)
    .filter(file =>
        (file.indexOf('.') !== 0) &&
        (file !== basename) &&
        (file.slice(-3) === '.js'))
    .forEach(file => {
        /* uncovered */ const model = sequelize.import(path.join(__dirname, file));
        /* uncovered */ db[model.name] = model;
    });

Object.keys(db).forEach(modelName => {
    /* uncovered */ if (db[modelName].associate) {
    /* uncovered */     db[modelName].associate(db);
    /* uncovered */ }
});

db.sequelize = sequelize;
db.Sequelize = Sequelize;

// Export everything
module.exports = db;

This is just a simple part of code which load all my Sequelize models (.js files) and create the associations.

While testing with istanbul, mocha and chai I can get full coverage over my API functions but can't get this code covered.

How should I test this?

If you want to test something using the fs, IMHO you should use dependency injection in your module. This will aloow you to mock the fs:

 /** * Database service */ // Dependencies const Sequelize = require('sequelize'); makeDb = (fs, path) => { let db = {} const basename = path.basename(module.filename); // Connection let sequelize = new Sequelize(process.env.DATABASE_URL, { logging: false }); // Models processing fs .readdirSync(__dirname) .filter(file => (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js')) .forEach(file => { /* uncovered */ const model = sequelize.import(path.join(__dirname, file)); /* uncovered */ db[model.name] = model; }); Object.keys(db).forEach(modelName => { /* uncovered */ if (db[modelName].associate) { /* uncovered */ db[modelName].associate(db); /* uncovered */ } }); db.sequelize = sequelize; db.Sequelize = Sequelize; return db } // Export everything module.exports = makeDb; 

Then you use your module like this:

 //app.js const fs = require('fs') const makeDb = require("./db") const db = makeDb(fs, path) /* * DO SOME STUFF */ //db.test.js const fakeFs = require('mock-fs') const makeDb = require("./db") const testDb = makeDb(fakeFs, path) 

This allows you to pass a fake FS to do your tests with mocka.

Mock-fs : https://www.npmjs.com/package/mock-fs

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM