I'm trying to write some tests in jest for an API that is intended to be shared with third parties. The inclusion method used by the third parties is a script tag which initiates the script but also passes along some data attributes via document.currentScript.
Here is a very cut down version of the code with the relevant parts:
// clientLib.js
export const getCurrentScript = () => document.currentScript;
export const initLib = () => {
const currentScript = getCurrentScript();
const reference = currentScript.getAttribute('data-reference');
const lang = currentScript.getAttribute('data-lang');
return new clientLib(reference, lang);
}
export class clientLib {
constructor(reference, lang) {
this._brand = reference;
this._market = lang;
}
}
window.clientLib = initLib();
// html
<script src="clientLib.js" data-reference="12345" data-lang="en-GB"></script>
What I'd like to be able to do in my test is something like this, but I've been unable to get anything to work:
// clientLib.test.js
import {
getCurrentScript,
initLib,
clientLib
} from './clientLib';
// here I want to mock the output of getCurrentScript() since document.currentScript does
// not exist, and I need the mock to return a script object with the two data attributes
// (ideally I need to be able to recreate this mock with both, either or none of the attributes)
// to test other cases
describe('initLib', () => {
it('returns a new instance of the library based on script attributes', () => {
window.clientLib = initLib();
// in here I should then be able to access properties on my lib on the window object
});
});
I did manage to get this working using an external setup file but for logistical reasons I don't think I can use this approach. I've tried to mock it in the test file itself and keep coming back to an "Invalid variable access: document" error. Is there a way to do this that I'm missing?