I am running into problems when trying to test a component with react-native-elements.
I am getting "Cannot use import statement outside a module" on import from react-native-elements.
My babel config is:
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: ['#babel/plugin-proposal-numeric-separator'],
};
jest config:
"jest": {
"preset": "react-native",
"moduleFileExtensions": [
"ts",
"tsx",
"js",
"jsx",
"json",
"node"
],
"setupFiles": [
"<rootDir>/__tests__/testSetup.ts"
]
}
The test is:
import { Questionnaire } from './Questionnaire';
import { render } from '#testing-library/react-native';
describe('Questionnaire', () => {
it('Should render', () => {
const { container } = render(<Questionnaire setSessionState={jest.fn()} />);
expect(container).toMatchSnapshot();
});
});
Any help would be appreciated!
Running the following test for closeDock. The test is passing at the moment but when I check its coverage, it does not change. using Jest and enzyme
closeDock = () => {
this.setState({ isVisible: false, tableMargin: 0 })
}
Any reason ?
Test:
beforeEach(() => wrapper = mount(<MemoryRouter keyLength={0}><HomeTab {...baseProps} /></MemoryRouter>));
it ('Test closeDock method ',() => {
wrapper.find('HomeTab').setState({
isVisible: false,
tableMargin: 0,
});
wrapper.update();
expect(wrapper.instance().closeDock).toEqual()
expect(wrapper.find('HomeTab').state('isVisible')).toBeFalsy();
expect(wrapper.find('HomeTab').state('tableMargin')).toEqual(0);
});
part of my package json related to coverage
"jest": {
"collectCoverageFrom": [
"src/**/*.{js,jsx}"
],
],
"setupFiles": [
"<rootDir>/config/polyfills.js"
],
"testMatch": [
"<rootDir>/src/**/__tests__/**/*.js?(x)",
"<rootDir>/src/**/?(*.)(spec|test).js?(x)"
],
I am replacing karma with jest and when I created all needed files and settings which you can see below. When I executed npm jest got an error:
Test suite failed to run
TypeError: Cannot set property '_eventListeners' of undefined
at Window.close (node_modules/jsdom/lib/jsdom/browser/Window.js:475:51)
I found a solution with editing node_modules/* files that don't make sense.
When I tried to switch testEnvironment to 'node' it's looked ok but I think that's not a good solution when it isn't node service project.
/jest.config.js
module.exports = {
coverageReporters: [
"html",
"text",
"cobertura"
],
globals: {
"ts-jest": {
tsConfig: "tsconfig.test.json",
babelConfig: true
}
},
moduleFileExtensions: [
"ts",
"tsx",
"js",
"jsx",
"json",
"node",
"d.ts",
"scss"
],
moduleNameMapper: {
"\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/test/mocks/fileMock.js",
"\\.(css|sass|scss)$": "<rootDir>/test/mocks/styleMock.js",
"^worker-loader!": "<rootDir>/test/mocks/workerLoaderMock.js",
"^resize-observer-polyfill$": "<rootDir>/test/mocks/resizeObserverPolyfillMock.js",
"applicationinsights-js": "<rootDir>/test/mocks/appInsightsMock.js"
},
reporters: [
"default",
"jest-junit"
],
setupFiles: [
"<rootDir>/test/mocks/setupJest.js"
],
setupFilesAfterEnv: [
"<rootDir>/test/mocks/matchMedia.js"
],
transform: {
"^.+\\.(js|jsx|ts|tsx|d.ts)$": "ts-jest"
},
testMatch: [
"<rootDir>/test/**/*-test.tsx"
],
timers: "fake"
};
/setupJest.js
global.Intl = require("intl");
global.fetch = require('jest-fetch-mock')
global.AppSettings = {
AUTHORITY_URL: "https://auth.blah.com",
INSTRUMENTATION_KEY: "APP_SETTINGS_KEY",
REALTIME_URL_BASE: "https//:realtime.blah.com"
};
my-test.js
import { Tooltip } from "../../src/components/shared";
import { expect, React, shallow } from "../test-utils";
describe("Tooltip with empty properties", () => {
const component = shallow(<Tooltip tooltipText="" />);
it("should have no text", () => {
expect(component.find("span.tooltip-text").text()).to.have.length(0);
});
it("should have 'tooltip-container' class", () => {
expect(component.hasClass("tooltip-container")).to.be.true;
});
it("should have child with 'tooltip-text' class", () => {
expect(component.childAt(0).hasClass("tooltip-text")).to.be.true;
});
});
describe("Tooltip with set properties", () => {
const expectedClass = "test-class";
const expectedText = "Test tooltip text";
const component = shallow(<Tooltip tooltipText={expectedText} className={expectedClass} />);
it("should have the expected text", () => {
expect(component.find("span.tooltip-text").text()).to.be.equal(expectedText);
});
it("should have the expected classes", () => {
expect(component.hasClass("tooltip-container")).to.be.true;
expect(component.hasClass(expectedClass)).to.be.true;
});
});
I am facing issue with jest testing..
Basically I have made configuration with following steps:
script in package.json:
"jest": {
"scriptPreprocessor": "<rootDir>/jest-script-preprocessor",
"moduleFileExtensions": [
"js",
"json",
"jsx"
],
"moduleNameMapper": {
"^.*[.](jpg|JPG|gif|GIF|png|PNG|less|LESS|css|CSS)$": "EmptyModule"
},
"preprocessorIgnorePatterns": [
"/node_modules/"
],
"unmockedModulePathPatterns": [
"<rootDir>/node_modules/react",
"<rootDir>/node_modules/react-dom",
"<rootDir>/node_modules/react-addons-test-utils",
"<rootDir>/EmptyModule.js"
]
},
"peerDependencies": {
"babel-core": "6.x | ^7.0.0-0"
}
And in jest-script-preprocessor.js
import babelJest from 'babel-jest'
module.exports = {
process: (src, filename) => {
return babelJest.process(src, filename)
.replace(/^require.*\.less.*;$/gm, '')
}
}
Let me know valuable way to get it resolve.
I am using JEST and Enzyme. In my eslint file I have added jest as true under env. But I get a lint error for shallow as I have included it globally. Error is- error 'shallow' is not defined no-undef
setupTests.js
//as we are accessing our application with a http://localhost prefix, we need to update our jest configuration
import { shallow, render, mount, configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
// React 16 Enzyme adapter
configure({ adapter: new Adapter() });
// Make Enzyme functions available in all test files without importing
global.shallow = shallow;
global.render = render;
global.mount = mount;
.eslintrc
{
parser: "babel-eslint",
"extends": ["airbnb"],
"env": {
"browser": true,
"jest": true
},
"rules": {
"max-len": [1, 200, 2, {ignoreComments: true}],
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
"no-underscore-dangle": [0, { "allow": [] }],
"jsx-a11y/label-has-associated-control": [
"error", {
"required": {
"every": [ "id" ]
}
}
],
"jsx-a11y/label-has-for": [
"error", {
"required": {
"every": [ "id" ]
}
}
]
}
}
app.test.js
import React from 'react';
import { LoginFormComponent } from '../../components';
describe('LoginForm', () => {
const loginform = shallow(<LoginFormComponent />);
it('renders correctly', () => {
expect(loginform).toMatchSnapshot();
});
});
package.json
"scripts": {
"dev": "webpack-dev-server --historyApiFallback true --port 8888 --content-base build/",
"test": "jest",
"lint": "eslint ./src",
"lintfix": "eslint ./src --fix"
},
"jest": {
"verbose": true,
"testURL": "http://localhost/",
"transform": {
"^.+\\.js$": "babel-jest"
},
"setupFiles": [
"./setupTests.js"
],
"snapshotSerializers": [
"enzyme-to-json/serializer"
]
},
The error comes in my app.test.js where I am trying to use shallow. Do I have to add something in my eslint config for enzyme the way I have made jest as true?
How about add global statement? eslint no-undef docs
/*global someFunction b:true*/
/*eslint no-undef: "error"*/
var a = someFunction();
b = 10;
or set global on .eslintrc (eslint global)
{
"globals": {
"shallow": true,
"render": true,
"mount": true
}
}
Updated .eslintrc
{
parser: "babel-eslint",
"extends": ["airbnb"],
"env": {
"browser": true,
"jest": true
},
"globals": {
"shallow": true
},
"rules": {
"max-len": [1, 200, 2, {ignoreComments: true}],
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
"no-underscore-dangle": [0, { "allow": [] }],
"jsx-a11y/label-has-associated-control": [
"error", {
"required": {
"every": [ "id" ]
}
}
],
"jsx-a11y/label-has-for": [
"error", {
"required": {
"every": [ "id" ]
}
}
]
}
}
Since globals are only used in test files the best practise is not to set them globally but only for the test files. That can be done by using overrides property with proper files glob:
overrides: [
{
files: "*.test.js",
globals: {
shallow: true,
render: true,
mount: true,
},
},
],
Full .eslintrc after addition in the snippet.
{
"parser": "babel-eslint",
"extends": ["airbnb"],
"env": {
"browser": true,
"jest": true
},
"rules": {
"max-len": [1, 200, 2, { "ignoreComments": true }],
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
"no-underscore-dangle": [0, { "allow": [] }],
"jsx-a11y/label-has-associated-control": [
"error",
{
"required": {
"every": ["id"]
}
}
],
"jsx-a11y/label-has-for": [
"error",
{
"required": {
"every": ["id"]
}
}
]
},
"overrides": [
{
"files": "*.test.js",
"globals": {
"shallow": true,
"render": true,
"mount": true
}
}
]
}