简体   繁体   中英

How do I test a void module for a logger feature using Jest

I have been trying to read up on writing test methods for void modules where there is a side-effect.

I can't seem to wrap my head around implementing it in my scenario where I have a module that takes in an array of loggers. This is to allow the client to implement multiple sources of logging in particular scenarios like using the console and logging to a persisted logging store (multiple sources if need be).

I have a level of abstraction which maps through concrete sources with the same contract.

The class abstracting from concrete classes has some logic to know which methods to be called and I want to test that that logic is sound but I am not sure how to do so. Since these methods are void am I right in thinking that I may need to call .toHaveBeenCalled to check for these side-effects?

Initialize logger

src/index.js

import logger from "./logger";
logger.init([console]);
logger.debug("Hello debug");

Logger

src/logger.js - abstraction expecting an array of concretes

function init(loggers) {
    ...
}

function debug(message) {
    writeToLogs(loggers, message, "debug");
}

function writeToLogs(loggers, message, type) {
    // I want to test this logic - multiple loggers and different calls mapped correctly
    loggers.forEach(logger => {
        switch (type) {
            case "debug":
                logger.debug(message);
                break;
            ...
        }
    }
}

module.exports = {
    init: init,
    debug: debug,
    ...
}

Console logger

src/logger/console.js - example of a concrete

function debug(message) {
    console.debug(message);
}

module.exports = {
    debug: debug,
    ...
}

Test

tests/logger.test.js

import logger from "../../src/logger";
test("logger writes information", () => {
    // What should I do here?
});

The console module is just writing to the console. In my opinion I don't think it is necessary to be tested unless it changes in the future. If I were to test it, how do I verify that the console has been written to? I would see this as an integration test as it is the actual implementation that integrates with the browsers' console.

I am using webpack 4.6.0 on node 9.5.0 with jest 22.4.3.

console is a side effect you have no control over by just mocking an import as it is not imported but an object in the global namespace of your module. Fortunately you can overwrite this from outside using the global object in your test file. So you can easily set anything you want in there

const debug = jest.fn()
const log = jest.fn()
const error = jest.fn()
global.console = {debug, error, log}

Now everytime console.log in your src/logger/console.js is called it will use the spy were you later on can test that it was called.

so now whenever

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