Jest mock ES6 module - javascript

How can I mock an ES6 module import using Jest?
For example we have the following structure:
// ../store.js
function getData(data) {
return data / 3;
}
export { getData };
// ../myModule.js
import { getData } from './store';
function myModule(param) {
return getData(param) * 4;
}
export { myModule };
// ./myModule.test.js
import { myModule ] from '../myModule';
test('2 x 4 equal 8', () => {
expect(getData(6)).toBe(8);
});

To mock ES2015 modules, your jest config needs to use babel to convert the modules first.
You'll want to yarn add --dev babel-jest babel-preset-env
and then your package.json should look something like this:
"jest": {
"moduleFileExtensions": [
"js",
"jsx"
],
"moduleDirectories": [
"node_modules"
],
"transform": {
"^.+\\.(js|jsx|mjs)$": "<rootDir>/node_modules/babel-jest"
},
"transformIgnorePatterns": [
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs)$",
"^.+\\.module\\.css$"
]
}
Secondly, in your .babelrc you need to specify your environment for test like so:
{
"presets": [
["env", "react"]
],
"env": {
"development": {
"presets": [["env"], "react"]
},
"production": {
"presets": [["env"], "react"]
},
"test": {
"presets": [["env"], "react"]
}
}
}
Once that's done, you can mock a module. For example, make a file called __mocks__/store.js (where the mocks folder is in the same level as your store.js file. Inside of your mocks file, you can do something like
const getData = () => return 42;
export { getData };
and in your myModule.test.js you need this line:
jest.mock('./store');
If you want, you can see a working example from one of my repositories here:
https://github.com/AnilRedshift/linkedINonymous/

If you want make automated test with jest, you have to include before the test/describe the next call
jest.mock('../myModule');
It returns void result from all functions.
Other alternative is mock mixed:
const mock: any = jest.genMockFromModule('../myModule');
mock.getData = jest.fn().mockImplementation(6);
The call to method getData returns 6.

Related

is it possible create unit for ts class by Jest?

Is it possible test this structire ? I have this structure
client/src/content/acs-signed-content-result.ts
export class AcsSignedContentResult {
testPubKey: string;
}
client/src/content/acs-signed-content.ts
import { AcsSignedContentResult } from "./content-result";
export class AcsSignedContent {
public async parse(acsSignContent: string, dsRootCert: string): Promise<AcsSignedContentResult> {
return new AcsSignedContentResult();
}
}
And my goal for test it, like separate peace, like unit test, like just execute parse method and check result, it should be object of class AcsSignedContentResult with some prop. SO for that I installed
package.json:
"ts-jest": "^27.1.4",
"ts-loader": "^9.2.6",
"typescript": "^4.6.4",
"#babel/preset-typescript": "^7.16.7",
"#types/jest": "^27.4.1",
"jest": "^28.0.3"
and
my conf
babel.config.js
module.exports = {
presets: [
['#babel/preset-env', {targets: {node: 'current'}}],
'#babel/preset-typescript',
],
};
jest.config.js
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
reporters: ['default', ['./node_modules/jest-html-reporter', {
includeConsoleLog: true,
includeFailureMsg: true,
includeSuiteFailure: true,
includeObsoleteSnapshots: true
}]],
roots: [
"<rootDir>/tests"
],
testMatch: [
"**/?(*.)+(spec|test).+(ts|tsx|js)"
]
};
then I created test but I'm not sure how it should be looks correctly ?
client/tests/acs-signed-content.test.js
with
import AcsSignedContent from '../src/content/acs-signed-content';
test('test acs-signed-content result', () => {
console.log("start test acs-signed-content result");
const acsSignedContent = new AcsSignedContent();
expect(acsSignedContent.parse("acsSignContent", "dsRootCert")).toBeDefined();
});
and I try this
import { AcsSignedContent } from "../src/content/acs-signed-content";
import {AcsSignedContentResult} from "../src/content/acs-signed-content-result";
jest.mock("../src/content/acs-signed-content-result");
it("should mock class B", () => {
const functionNameMock = jest.fn();
AcsSignedContentResult.mockImplementation(() => {
return {
functionName: functionNameMock
};
});
});
and when run test faced with error
● Test suite failed to run
Jest encountered an unexpected token
///
import AcsSignedContent from '../src/content/acs-signed-content';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1773:14)
How to correct create test for this goal ?

jest - Unexpected token 'export' for importing external library

I am going to test below component
WalletButton.jsx
import React from 'react';
import { WalletDialogButton } from "#solana/wallet-adapter-material-ui";
function WalletButton() {
return (
<WalletDialogButton>
{"CONNECT"}
</WalletDialogButton>
);
}
export default WalletButton;
The test case is below:
wallet-button.test.js
import {shallow} from "enzyme"
import React from 'react'
import WalletButton from "./WalletButton";
it('render WalletButton Component', () => {
expect(shallow(<WalletButton/>)).toMatchSnapshot();
})
When I run npm test, it shows error
● Test suite failed to run
Jest encountered an unexpected token
This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.
By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".
Here's what you can do:
• To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
• If you need a custom transformation specify a "transform" option in your config.
• If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.
You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html
Details:
/Users/CCCC/Desktop/SourceTree/my-project/node_modules/#solana/wallet-adapter-material-ui/lib/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){export * from './useWalletDialog';
I attempt to add
transformIgnorePatterns: [
"node_modules/(?!#solana/wallet-adapter-material-ui)",
]
in jest.config.js but still not working.
How to fix it?
jest.config.js
module.exports = {
moduleDirectories: ["node_modules", "src"],
moduleNameMapper: {
"^#/(.*)$": "<rootDir>/src/$1",
"\\.(css|scss)$": "identity-obj-proxy",
},
transform: {
"^.+\\.(js|jsx)$": "babel-jest",
".+\\.(png|jpg|svg|ttf|woff|woff2)$": "jest-transform-stub",
},
transformIgnorePatterns: [
"node_modules/(?!#solana/wallet-adapter-material-ui)",
],
setupFilesAfterEnv: ["<rootDir>/src/setupTests.js"],
snapshotSerializers: ["enzyme-to-json/serializer"],
};
Update 1
babelrc
{
"presets": [
"#babel/preset-env",
["#babel/preset-react", { "runtime": "automatic" }]
]
}

Webpack/Babel: ES6 keywords "async/await" unconverted in transpiled bundle.js

I'm using webpack and babel to transpile my ES6 javascript and React project to a bundle.js.
I'm getting this error:
bundle.js:90058: ERROR - Parse error. Semi-colon expected:
return async function (dispatch) {
Why is the "async" keyword still in the final transpiled bundle.js?
Here is my babel.config.js:
module.exports = {
presets: [
[
"#babel/preset-env",
{
useBuiltIns: "entry",
corejs: 3,
}
],
"#babel/preset-react"
],
plugins: [
"#babel/plugin-transform-runtime",
"#babel/plugin-proposal-class-properties",
"#babel/plugin-transform-async-to-generator",
"react-hot-loader/babel",
]
};
In my root index.jsx file I have these two imports:
import 'core-js/stable';
import 'regenerator-runtime/runtime';
The actual code in question is the following:
export const getUser = () => async (dispatch) => { ... }
...which gets transpiled to this:
var getUser = function getUser() {
return async function (dispatch) {
...
}
}
Is there some other configuration needed to convert those async/await keywords?

Jest css-modules SyntaxError: Unexpected token

I have set up my jest to allow static files after following their documentation on how to do so, but I still recieve the following error.
How can I can it to pass and create a snapshot.
Terminal Error
FAIL src/components/Splash/Splash.test.js
● Test suite failed to run
/var/www/com/src/components/shared/logo/_Logo.css:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){.logo {
^
SyntaxError: Unexpected token .
3 |
4 |
> 5 | import logo from './_Logo.css';
6 | import * as font from '../font/fontello.css';
Splash.test.js
import { shallow } from 'enzyme';
import { shallowToJson } from 'enzyme-to-json';
import Splash from './Splash';
it('Splash page is rendered', () => {
const result = shallow(
<Splash />,
);
expect(shallowToJson(result)).toMatchSnapshot();
});
Jest Config
"jest": {
"snapshotSerializers": [
"enzyme-to-json/serializer"
],
"setupTestFrameworkScriptFile": "./node_modules/jest-enzyme/lib/index.js",
"moduleFileExtensions": [
"js"
],
"moduleDirectories": [
"node_modules"
],
"testPathIgnorePatterns": [
"<rootDir>/node_modules/",
"<rootDir>/app/"
],
"moduleNameMapper": {
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\.(css|less)$": "identity-obj-proxy"
}
},
"transform": {
"^.+\\.js$": "babel-jest"
}
}
It may work who use create-react-app from feb 2018.
I partially followed the docs jest webpack to make it work.
Also found out the moduleNameMapper cannot be overriden in package.json but in jest.config.js it does the trick.
Unfortunately i havent found any docs about why it does but here is my answer.
Here is my jest.config.js:
module.exports = {
...,
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\.(scss|sass|css)$": "identity-obj-proxy"
}
}
and it skips scss files and #import quite well.
I added to devDependencies identity-obj-proxy
There is a small mistake: moduleNameMapper: {moduleNameMapper{}} should just be moduleNameMapper:{}
"moduleNameMapper": {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
"\\.(css|less)$": "identity-obj-proxy"
}

How to solve issue in jest unit test?

I have a unit test for a ReactJs/Typescript project that has a reference to a module called nock.js, and using jest:
import nock from 'nock'
...
afterEach(() => {
nock.cleanAll();
})
When I run the test I get an error in the .cleanAll statement:
TypeError: nock_1.default is not a function
However when I change the import statement to :
var nock = require('nock');
The issue is solved. How can I still use import instead of require ? Is this an issue with the jest configuration? This is the config:
"jest": {
"transform": {
"^.+\\.(ts|tsx)$": "<rootDir>/node_modules/ts-jest/preprocessor.js"
},
"moduleFileExtensions": [
"ts",
"tsx",
"js"
],
"testRegex": "/__tests__/.*\\.(ts|tsx|js)$"
},
If a module has a default export, you can use:
import nock from 'nock'
But if it doesn't have a default export, you'll need to use:
import * as nock from 'nock'
I met the same exact issue, and fixed it by adding the following config to my tsconfig.json:
{
...
"esModuleInterop": true
...
}

Categories