Search code examples
node.jstypescriptjestjsts-jest

jest test with xmljs GLOBAL not defined


currently I am writing an App using

  • NodeJS v13.12.0
  • Jest 25.4.0
  • xmljs 0.3.2
  • typescript 3.8.3
  • ts-jest 25.4.0

This App should mimic a CalDAV Server. For this reason, I rely on the module xmljs, which is (after my research) the only module giving me a direct path method for finding properties in the XML.

In the node Container, the App runs fine without any errors. But When I start a test with Jest, the test fails with the error

ReferenceError: GLOBAL is not defined
      at node_modules/xmljs/core.js:46:2
      at Object.<anonymous> (node_modules/xmljs/core.js:176:3)
      at node_modules/xmljs/XmlParser.js:3:11
      at Object.<anonymous> (node_modules/xmljs/XmlParser.js:204:3) 

I now know, that this error originates from the xmljs module trying to set the GLOBAL variable, which in NodeJS resolved to global. But this does not happen in jest.

My code works like following:

import XmlParser = require("xmljs");

/*
* data is the body of a PROPFIND request
*/
new XmlParser({ strict: true }).parseString(data, (err, xmlNode) => {
    // omit err
    xmlNode.path(["propfind", "prop"], true);

    const propertiesObj: XmlNode[] = childs[0].children;
    const properties: string[] = [];

    Object.keys(propertiesObj).forEach(n => {
        properties.push(n);
    });

    logger.silly("Returning properties: %O", properties);
});

Can anyone

  1. Show me a module to use instead without requiring huge modifications of my code

    • Which supports a pure js implementation without using node-gyp (since it may be used on windows server)
  2. Show me how to make a workaround in jest to spoof this GLOBAL variable being set in xmljs

I appreciate your help


Solution

  • You can set the value of GLOBAL in the setup of your tests. It seems that the GLOBAL variable is the deprecated form of the global in node.

    In your jest.config.js file you can add a setup file through the setupFiles option:

    module.exports = {
        [...] // Other configurations
        setupFiles: ['<rootDir>/define-deprecated-global.js']
    };
    

    And in the file define-deprecated-global you can define the GLOBAL variable as:

    global.GLOBAL = global;