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?
src/index.js
import logger from "./logger";
logger.init([console]);
logger.debug("Hello debug");
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,
...
}
src/logger/console.js - example of a concrete
function debug(message) {
console.debug(message);
}
module.exports = {
debug: debug,
...
}
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.