I am working on a React-Native project that is ready for production but dont have one single test on it.
It looked like an easy task, but its driving me nuts for 3 days now.
Basically I have a simple test on my tests folders, checking if it builds correctly.
import React from 'react';
import App from '../App';
// Note: test renderer must be required after react-native.
import renderer from 'react-test-renderer';
it('renders correctly', () => {
const tree = renderer.create(<App />).toJSON();
expect(tree).toMatchSnapshot();
});
This is my babel and jest config
jest.config.js
module.exports = {
preset: 'react-native',
automock: false,
setupTestFrameworkScriptFile: './__mocks__/mockFirebase',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
// transformIgnorePatterns: [
// 'node_modules/(?!(#react-native|react-native|#react-native-firebase|react-native-firebase|react-native-push-notification-popup)/)',
// ],
transformIgnorePatterns: [
'node_modules/(?!(jest-)?#?react-native|#react-native-community|#react-navigation)'
],
};
babel.config
module.exports = function(api) {
api.cache(true);
const presets = [
[
'#babel/preset-env',
{
modules: 'auto',
targets: {
browsers: ['defaults']
},
useBuiltIns: 'entry'
}
],
['module:metro-react-native-babel-preset'],
'#babel/react',
'#babel/preset-flow',
];
const plugins = [
'#babel/plugin-proposal-class-properties',
'#babel/transform-runtime',
'add-module-exports',
'babel-plugin-dynamic-import-node'
];
return {
presets,
plugins
};
};
When trying to run a simple npm test
Im getting:
FAIL __tests__/App-test.js
● Test suite failed to run
TypeError: Cannot read properties of undefined (reading 'showErrorDialog')
at node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:12564:62
at Object.<anonymous> (node_modules/react-native/Libraries/Renderer/implementations/ReactNativeRenderer-dev.js:23046:4)
at Object.<anonymous> (node_modules/react-native/Libraries/Renderer/shims/ReactNative.js:21:17)
Test Suites: 1 failed, 1 total
Tests: 0 total
Snapshots: 0 total
Time: 2.389 s
Ran all test suites.
I dont know what to do anymore. If someone can give me a light.
Related
I have a React Native app in which I installed and used jail-monkey to check if the device is rooted. As soon as I added it, some of my Jest tests started failing with the following error:
SyntaxError: Cannot use import statement outside a module
> 3 | import JailMonkey from 'jail-monkey';
After googling I came upon this stack overflow thread which has many answers but neither of which helped me. That being said I imagine this problem has to do with the babel and jest configs - How to resolve "Cannot use import statement outside a module" in jest
My babel.config.js looks like this:
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
[
require.resolve('babel-plugin-module-resolver'),
{
cwd: 'babelrc',
extensions: ['.ts', '.tsx', '.ios.tsx', '.android.tsx', '.js'],
alias: {
'#src': './src',
},
},
],
[
'module:react-native-dotenv',
{
moduleName: 'react-native-dotenv',
},
],
// Reanimated needs to be at the bottom of the list
'react-native-reanimated/plugin',
],
};
And my jest.config.js looks like this:
const { defaults: tsjPreset } = require('ts-jest/presets');
/** #type {import('#jest/types').Config.InitialOptions} */
module.exports = {
...tsjPreset,
preset: 'react-native',
transform: {
'^.+\\.jsx$': 'babel-jest',
},
// Lists all react-native dependencies
// that don't have compiled ES6 code
// and need to be ignored by the transformer
transformIgnorePatterns: [
'node_modules/(?!(react-native' +
'|react-navigation-tabs' +
'|react-native-splash-screen' +
'|react-native-screens' +
'|react-native-reanimated' +
'|#react-native' +
'|react-native-vector-icons' +
'|react-native-webview' +
')/)',
],
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
moduleNameMapper: {
// Help Jest map the #src's added by babel transform
'^#src(.*)$': '<rootDir>/src$1',
// Allow Jest to mock static asset imports
'\\.(jpg|jpeg|png|gif|eot|otf|webp|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$':
'<rootDir>/__mocks__/assetMock.js',
// Mock SVG Component imports (from React Native SVG)
'\\.svg': '<rootDir>/__mocks__/svgMock.js',
},
setupFiles: ['./jest.setup.js'],
setupFilesAfterEnv: ['#testing-library/jest-native/extend-expect'],
};
I solved this issue by including jail-monkey in my transformIgnorePatterns on jest.config.js and them mocking the jailmonkey.js. In my case I have the file on __mocks__/jail-monkey/index.js with the following content:
export default {
jailBrokenMessage: () => '',
isJailBroken: () => false,
androidRootedDetectionMethods: {
rootBeer: {
detectRootManagementApps: false,
detectPotentiallyDangerousApps: false,
checkForSuBinary: false,
checkForDangerousProps: false,
checkForRWPaths: false,
detectTestKeys: false,
checkSuExists: false,
checkForRootNative: false,
checkForMagiskBinary: false,
},
jailMonkey: false,
},
hookDetected: () => false,
canMockLocation: () => false,
trustFall: () => false,
isOnExternalStorage: () => false,
isDebuggedMode: () => Promise.resolve(false),
isDevelopmentSettingsMode: () => Promise.resolve(false),
AdbEnabled: () => false,
};
I am receiving the error SyntaxError: Cannot use import statement outside a module when running a simple test on a React/Typescript component and not sure the best way of using modules in a React/Typescript project with Babel, webpack, and jest.
Here is my babel.config.js :
const isTest = String(process.env.NODE_ENV) === 'test'
const isProd = String(process.env.NODE_ENV) === 'production'
module.exports = {
presets: [
['#babel/preset-env', { modules: isTest ? 'commonjs' : false }],
'#babel/preset-typescript',
};
jest.config.js
module.exports = {
"roots": [
"<rootDir>/src"
],
"testMatch": [
"**/__tests__/**/*.+(ts|tsx|js)",
"**/?(*.)+(spec|test).+(ts|tsx|js)"
],
"transform": {
"^.+\\.(ts|tsx)$": "ts-jest"
},
"moduleFileExtensions": ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],
}
Here is the simple test I am trying to run:
import { render } from '#testing-library/react'
import AppRouter from '../router'
test('it works!', () => {
render(<AppRouter />)
})
Please help!
Solution
Be sure to check your testRegex in your jest.config.js file and the testEnvironment is set correctly with testEnvironment: "jsdom" if you are using ES6 modules for testing.
I'm trying to use a package: quoters
this is app.svelte file. the same code works fine for react and other places in JS.
<script>
import Quote from "quoters";
let quote = "";
let category = "QUOTE";
function handleCategory() {
quote = new Quote(category).get();
}
</script>
when I am trying to run the code. i get the following error: "Uncaught ReferenceError: exports is not defined". I checked the line it is referencing to.
it contains definition for exports inside the quoters package.
Object.defineProperty(exports, "__esModule", { value: true });
I've tried everything like babel and commonjs. maybe i am missing something. please can anyone tell me what is the issue and also fix for this issue.
my rollup config file for reference:
import svelte from "rollup-plugin-svelte";
import commonjs from "#rollup/plugin-commonjs";
import resolve from "#rollup/plugin-node-resolve";
import livereload from "rollup-plugin-livereload";
import { terser } from "rollup-plugin-terser";
import css from "rollup-plugin-css-only";
import copy from "rollup-plugin-copy";
import json from "#rollup/plugin-json";
import builtins from "rollup-plugin-node-builtins";
import globals from "rollup-plugin-node-globals";
import replace from "#rollup/plugin-replace";
import babel from "#rollup/plugin-babel";
import nodePolyfills from "rollup-plugin-node-polyfills";
const production = !process.env.ROLLUP_WATCH;
function serve() {
let server;
function toExit() {
if (server) server.kill(0);
}
return {
writeBundle() {
if (server) return;
server = require("child_process").spawn(
"npm",
["run", "start", "--", "--dev"],
{
stdio: ["ignore", "inherit", "inherit"],
shell: true,
}
);
process.on("SIGTERM", toExit);
process.on("exit", toExit);
},
};
}
export default {
input: "src/main.js",
output: {
sourcemap: true,
format: "iife",
name: "app",
file: "public/build/bundle.js",
exports: "auto",
},
moduleContext: {
"node_modules/quoters/dist/parseData.js": "window",
},
plugins: [
svelte({
compilerOptions: {
// enable run-time checks when not in production
dev: !production,
},
}),
nodePolyfills(),
json(),
copy({
targets: [
{
src: "node_modules/bootstrap/dist/**/*",
dest: "public/vendor/bootstrap",
},
],
}),
// we'll extract any component CSS out into
// a separate file - better for performance
css({ output: "bundle.css" }),
// If you have external dependencies installed from
// npm, you'll most likely need these plugins. In
// some cases you'll need additional configuration -
// consult the documentation for details:
// https://github.com/rollup/plugins/tree/master/packages/commonjs
babel({
exclude: "node_modules/**", // only transpile our source code
}),
resolve({
dedupe: ["svelte"],
browser: true,
preferBuiltins: false,
}),
commonjs(),
// In dev mode, call `npm run start` once
// the bundle has been generated
!production && serve(),
// Watch the `public` directory and refresh the
// browser on changes when not in production
!production && livereload("public"),
// If we're building for production (npm run build
// instead of npm run dev), minify
production && terser(),
],
watch: {
clearScreen: false,
},
};
I have an issue with my Jest test suites not running because they are not importing correctly. I have set up some 'alias' paths in jest.config.js but for whatever reason, I get errors in the form:
Test suite failed to run
src/__tests__/app.test.tsx:3:40 - error TS2307: Cannot find module '#/render/index'.
where I am trying to import like
import { render, fireEvent, act } from '#/render/index';
This should be resolving to /src/testUtils/render/index as per my jest.config.js file:
// jest.config.js
// eslint-disable-next-line #typescript-eslint/no-var-requires
const { defaults } = require('jest-config');
const ignores = [
'[/\\\\]node_modules[/\\\\].+\\.(ts|tsx|js|jsx|mjs)$',
'/__tests__/helpers/',
'__mocks__',
];
module.exports = {
roots: ['<rootDir>/src'],
preset: 'ts-jest',
setupFiles: ['<rootDir>/src/testUtils/globals/index.ts'],
setupFilesAfterEnv: ['<rootDir>/src/testUtils/jest.setup.ts'],
moduleFileExtensions: [...defaults.moduleFileExtensions, 'ts', 'tsx'],
moduleDirectories: ['src', 'src/testUtils/render/', 'node_modules', 'src/testUtils/globals/'],
moduleNameMapper: {
// Tell jest to look in the src/testUtils/render/ dir when we use #/
'^#/render/(.*)$': '<rootDir>/src/testUtils/render/$1',
'^#/globals/(.*)$': '<rootDir>/src/testUtils/globals/$1',
},
modulePaths: ['<rootDir>'],
testMatch: ['<rootDir>/**/__tests__/**/*.test.+(ts|tsx)', '<rootDir>/**/*.test.ts'],
testURL: 'http://localhost',
transform: {
'\\.(ts|js)x?$': 'ts-jest',
'^.+\\.css$': '<rootDir>/config/jest/cssTransform.js',
'^(?!.*\\.(mjs|css|json)$)': '<rootDir>/config/jest/fileTransform.js',
},
transformIgnorePatterns: [...ignores],
coverageDirectory: '<rootDir>/src/testUtils/coverage',
collectCoverageFrom: ['<rootDir>/**/*.{ts,tsx,mjs}', '<rootDir>/**/**/*.{ts,tsx,mjs}'],
coveragePathIgnorePatterns: [
...ignores,
'<rootDir>/testUtils/',
'<rootDir>/src/serviceWorker.ts',
],
collectCoverage: false,
coverageThreshold: {
global: {
branches: 40,
functions: 40,
lines: 40,
statements: 40,
},
},
prettierPath: './node_modules/prettier',
timers: 'fake',
verbose: true,
errorOnDeprecated: true,
globals: {
'ts-jest': {
tsConfig: 'tsconfig.extend.json',
diagnostics: true,
},
},
extraGlobals: ['Math'],
notify: true,
watchPathIgnorePatterns: ['<rootDir>/src/serviceWorker.ts'],
snapshotSerializers: ['jest-serializer-html'],
};
I've tried updating Jest to latest, and then to 25.5.4, but nothing has changed anything. This used to work at some point in the past so I don't know what exactly to do to fix it. Would someone have any ideas?
Tried updating ts-jest and jest both to 26.0.0. Still no luck.
question about React unit tests.
I've a ReactJs project and these is the current setup:
based on create-react-app
built with ejected Webpack
lots of Webpack plugins, as sass-extract-loader
based on some aliases built in webpack.config.dev.js
Now, I am installing a Jest environment to write tests both for simple javascript files and also for React components.
Simple javascript unit tests are working properly
But the test configuration is not working properly for unit tests of React components.
What is not working is the resolving of some requires that use aliases -defined in Webpack- within React components.
const motionConfig = require(`scssConfig/shared/motions.scss`)
scssConfig is an alias configured in the webpack.config.dev.js but in the Jest environment, when executing jest --config jest.config.json, an error pops out because the required file is not read / found and when I try to access its content, this is the error displayed coming out of the line const durationConfig = motionConfig.duration
TypeError: Cannot read property 'duration' of undefined
So basically it is failing the setup of the React environment, because the React component unit test is not yet run.
this is my jest.config.json
{
"bail": true,
"setupFilesAfterEnv": ["<rootDir>/jest.setup.js"],
"testMatch": [
"<rootDir>/src/app/**/?(*.)+(spec|test).(js|ts)?(x)"
],
"testPathIgnorePatterns": [
"<rootDir>/build/",
"<rootDir>/generated/",
"<rootDir>/node_modules/",
"<rootDir>/public/"
],
"snapshotSerializers": ["enzyme-to-json/serializer"],
"collectCoverageFrom": [
"src/**/*.{js,jsx,ts,tsx}"
],
"testEnvironment": "node",
"testURL": "http://localhost",
"transform": {
"^.+\\.(js|jsx|ts|tsx)$": "<rootDir>/node_modules/babel-jest",
"^.+\\.(css|scss)$": "<rootDir>/config/jest/cssTransform.js",
"^(?!.*\\.(js|jsx|ts|tsx|json)$)": "<rootDir>/config/jest/fileTransform.js"
},
"transformIgnorePatterns": [
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx|ts|tsx)$",
"^.+\\.module\\.(css|scss)$"
],
"moduleDirectories": [
"node_modules",
"<rootDir>/../library"
],
"moduleNameMapper": {
"\\.(css|scss)$": "identity-obj-proxy",
"#company/library/(.*)": "<rootDir>/../library/$1"
},
"resolver": null,
"moduleFileExtensions": [
"js",
"jsx",
"ts",
"tsx",
"scss",
"css"
]
}
and this is jest.setup.js
import Adapter from 'enzyme-adapter-react-16'
import { shallow, mount, configure } from 'enzyme'
import { format } from 'util'
import React from 'react'
import dotenv from 'dotenv'
import registerRequireContextHook from 'babel-plugin-require-context-hook/register'
dotenv.config({ path: __dirname + '/../.env' })
registerRequireContextHook()
configure({ adapter: new Adapter() })
let global
global.React = React
global.shallow = shallow
global.mount = mount
class ConsoleError extends Error {}
if (global.console) {
const throws = jest.fn((message, ...rest) => {
if (!(message instanceof ConsoleError)) {
const err = new ConsoleError(format(message, ...rest))
Error.captureStackTrace(err, throws)
throw err
}
})
global.console = {
...global.console,
error: throws,
warn: throws,
exception: throws
}
}
and this is .babelrc.js
const commonPlugins = [
[
require.resolve('babel-plugin-module-resolver'),
{
root: ['./src/app/'],
alias: {
'scssConfig': '../path/to/scssConfig',
}
}
]
]
module.exports = {
plugins: [...commonPlugins]
}
I think the json configuration is properly done but there is something missing.... what? any tips to make it working properly? thanks a lot
Fixed it like that
the require got replaced by the import
import motionScss from 'scssConfig/shared/gl-config-motion.scss'
in the jest.config.json I did this update
"\\.(scss)$": "<rootDir>/src/app/mocks/tests/scss.js",
"\\.(css)$": "identity-obj-proxy",
and this is the src/app/mocks/tests/scss.js
module.exports = { global: { '$motion': { duration: {}, ease: {} }}};