I am in the process of moving an old JS codebase to modern JS. First step though is to add some tests to the current codebase. The current code base is essentially a bunch of individual JS files each wrapped in an IIFE.
This in itself is a problem for tests because, unless something is exposed to the global object, you cannot reach into the IIFE. Some of the code I am refactoring to be simple JS object with properties, which is attached to a namespace(namespace
below is just a placeholder name) on the global object, for example:
var namespace = window.namespace || {};
var paymentsHandlerUtils = {
getNewValue: function(selectedAmount) {
'use strict';
return selectedAmount < 1 || isNaN(selectedAmount)
? ''
: '$' + selectedAmount;
},
getSelectedAmount: function(value) {
'use strict';
return value % 1 === 0 ? parseInt(value) : parseFloat(value).toFixed(2);
}
};
namespace.paymentsHandlerUtils = paymentsHandlerUtils;
My question is, how would you go about testing this with Jest? I have tried requiring the above as follows:
const paymentsHandlerUtils = require('../js/components/payments/payments-handler-utils.js');
This runs, but the paymentsHandlerUtils
object is just an empty {}
. Not surprising, as nothing is being returned by simply executing the JS. However, window.namespace
is also undefined. Seems like the code is not being executed in the context of jsDOM, so the global(s) is not created.
Is there a way to get this to work, or is this simply not a use case for Jest? Thanks in advance.
I don’t think there is a way to access module globals when imported as it goes against the principle of encapsulated modules in the first place.
An alternative which would require the least refactoring would be to add the following code to all your modules:
if (typeof exports === "object") {
module.exports = paymentsHandlerUtils;
}
namespace.paymentsHandlerUtils = paymentsHandlerUtils;
It is inspired by the old UMD (Universal Module Definition). The condition detects if you are running in a commonjs environment and exports your variable. You will then be able to require it in your tests:
const paymentsHandlerUtils = require('../js/components/payments/payments-handler-utils.js');
Otherwise you need to use another test suite that works in the browser, because Jest doesn’t.
Good luck to your migrations!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With