What is the current behavior?
I'm struggling to find a way to mock a function within a Singleton Class (ES6).
Consider the following contentLoader.js
// unique key
const _contentLoaderSingleton = Symbol("contentLoaderSingleton");
/**
* Content Loader Singleton Class
*/
class ContentLoaderSingleton {
constructor(contentLoaderSingletonToken) {
if (_contentLoaderSingleton !== contentLoaderSingletonToken) {
throw new Error("Cannot instantiate directly.");
}
// Cached images
this._imgLoaded = {};
this._imgAlias = {};
}
static get instance() {
if (!this[_contentLoaderSingleton]) {
this[_contentLoaderSingleton] = new ContentLoaderSingleton(
_contentLoaderSingleton
);
}
return this[_contentLoaderSingleton];
}
_loadImage(path) {
return new Promise((resolve, reject) => {
let image = new Image();
image.src = path;
image.onload = () => resolve(image);
image.onerror = () =>
reject(new Error("Image is not defined. Unable to load it."));
});
}
async loadImage(path, alias) {
let image;
try {
image = await this._loadImage(path);
} catch (error) {
// log and rethrow
console.error(error);
throw error;
}
// cache the loaded image:
this._imgLoaded[path] = image;
if (alias) {
this._imgAlias[alias] = path;
}
}
}
/**
* Content Loader alias to Content Loader Singleton instance
*/
export const ContentLoader = ContentLoaderSingleton.instance;
Is there a way to mock the function _loadImage while keeping the singleton intact?
I have come across rewire (babel plugin), but if I include it in the babel plugins, it raises the following error (jest watch mode):
babel-plugin-jest-hoist: The module factory of 'jest.mock()' is not allowed to reference any out-of-scope variables.
Invalid variable access: _extends
What's the best approach here?
Thanks!
Please provide your exact Jest configuration and mention your Jest, node, yarn/npm version and operating system.
"jest": "20.0.4"
"babel-jest": "20.0.3"
Babel jest configuration:
{
"env": {
"test": {
"plugins": [
"transform-runtime",
// "rewire"
],
"presets": [
"es2015",
"stage-3"
]
}
}
}
It turns out to be easier than anticipated:
let ContentLoader = require.requireActual("../src/contentLoader.js").ContentLoader;
ContentLoader._loadImage = function() {
return "teeehee";
};
module.exports = ContentLoader;
If you have any other suggestions, let me know!
Thanks
Most helpful comment
It turns out to be easier than anticipated:
If you have any other suggestions, let me know!
Thanks