Node.js: exporting class/prototype vs. instance
Asked Answered
H

1

8

As I do most of my programming in Java, I find it compelling to export a class in a Node.js module instead of an object instance, e.g.:

class Connection {
    constructor(db) {
        this.db = db;
    }
    connect(connectionString) {
        this.db.connect(connectionString);
    }
}
exports.Connection = Connection;

Since doing this would require instantiating the class multiple times across dependent modules, I still need to export an already existing instance for use in the rest of the production code. I do it in the same module:

exports.connection = new Connection(require("mongoose"));

This allows for some testability, as the real dependency can be swapped in a test:

const Connection = require("./connection").Connection;

describe("Connection", () => {
    it("connects to a db", () => {
        const connection = new Connection({connect: () => {}});
        // ...
    });
});

This approach works, but it has a strange feel to it as I'm mixing two patterns here: exporting a prototype (for unit tests) and an instance (for the production code). Is this acceptable? Should I continue with this or change to something different? If so, what is the preferred pattern?

Hives answered 26/5, 2017 at 11:5 Comment(0)
H
0

You're right, it's a bad coding style, but actually you can write a function which, depending on the received parameter, returns either the single instance (for the whole application), or the class itself (for testing). Something like this:

class MyClass() {}

const instance = new MyClass();

function getInstanceOrClass(isTesting) {
    if(isTesting) {
        return MyClass;
    } else {
        return instance;
    }
}

exports.getInstanceOrClass = getInstanceOrClass;

// in other files

const getInstanceOrClass = require('./yourFileName');

const classSingletonInstance = getInstanceOrClass();

// in test files

const getInstanceOrClass = require('./yourFileName');

const MyClass = getInstanceOrClass(true);
Hunsaker answered 19/1, 2022 at 15:52 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.