I'm trying to use jest to start doing some unit testing but I've come across this error that a lot of people seem to be getting but I can't seem to figure it out.
Here's is what I'm trying to do (and I realize requirejs isn't supported):
jest.mock("../widgets/", () => {
return <button>button</button>;
});
describe('TextInput', () => {
describe('when user inputs a value', () => {
it('calls correct function to handle change', () => {
const handleChange = jest.fn();
const value = "test"
const wrapper = shallow(<TextInput handleChange={handleChange} />);
const textInputElement = wrapper.find("#textfield");
textInputElement.simulate('change', {target: { value }})
expect(handleChange).toHaveBeenCalledTimes(1);
});
});
});
import React from "react";
import ReactDOM from "react-dom";
import * as TestUtils from "react-dom/test-utils";
import { TextInput } from "../widgets/";
and here is my package.json
"jest": {
"collectCoverageFrom": [
"src/**/*.js"
],
"setupFiles": [
],
"testMatch": [
"**/src/**/?(*.)+(test).js"
],
"testEnvironment": "node",
"testURL": "http://localhost",
"transform": {
"^.+\\.(js)$": "./node_modules/babel-jest",
"^.+\\.css$": "./config/jest/cssTransform.js",
"^(?!.*\\.(js|jsx|mjs|css|json)$)": "./config/jest/fileTransform.js"
},
"transformIgnorePatterns": [
"[/\\\\]node_modules[/\\\\].+\\.(js|jsx|mjs)$"
],
"moduleNameMapper": {
"^react-native$": "react-native-web"
},
"moduleFileExtensions": [
"web.js",
"js",
"json",
"web.jsx",
"jsx",
"node",
"mjs"
]
}
Upon running jest, I get the error ReferenceError: define is not defined and here is a more detailed error:
I would appreciate any help! Been pulling my hair out over this for the past few days :-(
Edit: Just realized that according to docs toHaveBeenCalledTimes should in fact also work. Anyway you could give mock.calls.length a try.
As far as I know assertions on jest function mocks do not work like this
expect(handleChange).toHaveBeenCalledTimes(1);
You should give this a try
expect(handleChange.mock.calls.length).toBe(1);
As described in the docs
Related
First time writing tests in typescript for my expo project. I've got some errors in my Typescript (the actual typing), but the functionality works. When I run my tests, ts-jest doesnt allow the tests to run since the types are incorrect (even though the functionality works). Is there some setting to allow ts-jest to run regardless of type errors?
App.test.tsx
import React from "react";
import renderer from "react-test-renderer";
import SignUp from "../screens/Auth/screens/SignUp";
describe("<App />", () => {
it("has 1 child", () => {
const tree = renderer.create(<SignUp />).toJSON();
console.log(tree);
});
});
jest.config.js
const { defaults: tsjPreset } = require("ts-jest/presets");
/** #type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: "react-native",
transform: {
"^.+\\.jsx$": "babel-jest",
"^.+\\.tsx?$": [
"ts-jest",
{
tsconfig: "tsconfig.spec.json",
},
],
},
moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"],
};
babel.config.js
/** #type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
presets: ['module:metro-react-native-babel-preset'],
}
I'm new to using Jest and I'm trying to test my helper function.
I'm not using any Typescript at the moment.
This is the error I get when I run npm run test:
TypeError: Cannot destructure property 'print' of '_graphql.default' as it is undefined.
helper.test.js:
import getDuplicateError from '../../helpers/auth'
test('Check if email already exists', () => {
error = "duplicate_email_key";
expect(getDuplicateError(error)).toBe(true);
})
auth.js:
import graphql from "graphql";
const { print } = graphql;
export const getDuplicateError = (errors) => {
/*...*/ // Actual implementation doesn't use print
};
jest.config.js
export default {
preset: 'ts-jest/presets/js-with-babel',
testEnvironment: "node",
transform: {
"^.+\\.(js|jsx)?$": "babel-jest",
'^.+\\.(ts|tsx)?$': 'ts-jest',
},
transformIgnorePatterns: [
"node_modules/(?!variables/.*)"
],
coveragePathIgnorePatterns: [
"/node_modules/"
]
};
babel.config.json
{
"presets": [
[
"#babel/preset-env",
{
"targets": {
"node": true
}
}
]
]
}
package.json
"devDependencies": {
"#babel/preset-env": "^7.12.17",
"babel-jest": "^26.6.3",
"jest": "^26.6.3",
"ts-jest": "^26.5.1",
"ts-node": "^9.1.1"
}
Even though print isn't being used for this function (it is used in other ones), the overall issue is that I can't test anything right now because of this issue, and will also need to be able to use it for other functions.
Is there a configuration that I need for destructuring to work? Am I not able to use destructuring on other libraries?
Will definitely prefer to be able to destructure like this because I use a lot of destructuring in my code.
Let me know if I need to provide anything else.
try to import like this
import * as graphql from "graphql";
const {print}=graphql;
graphql is not exported from graphql package and hence it is undefined. Again when you try to destructure print from it, It is throwing error.
I had to provide a mock for this one for it to ignore the destructure. I'm not sure if this is the best way to go about this but this is one solution to go past it. If someone knows of another way to go about it, I'd appreciate other responses!
jest.mock(
'graphql',
() => {
const mPrint = { t: jest.fn().mockReturnValue('test') };
return {
print: jest.fn(() => mPrint),
};
},
{ virtual: true },
);
I am new to Jest. I'm trying to run it with the most basic test:
//App-test.js
import 'react-native';
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();
});
But I keep getting the Error: ● Test suite failed to run
TypeError: Cannot read property 'createAnimatedComponent' of undefined
at Object.<anonymous> (node_modules/react-native-screens/lib/commonjs/index.js:27:23)
at Object.<anonymous> (node_modules/react-navigation-tabs/lib/commonjs/navigato/createBottomTabNavigator.tsx:10:1)
My jest config in my package.json looks like this:
"jest": {
"preset": "react-native",
"globals": {
"__DEV__": true
},
"transformIgnorePatterns": [
"node_modules/(?!react-native-screens|react-navigation-tabs)/",
"node_modules/(?!react-native-payfort-sdk|react-native|Hacktor|react-native-button|react-navigation)/"
],
"haste": {
"defaultPlatform": "android",
"platforms": [
"android",
"ios"
]
}
}
and my babel.config.js looks like this:
// babel.config.js
module.exports = function(api) {
api.cache(true);
const presets = [
[
'#babel/preset-env',
{
modules: 'auto',
useBuiltIns: 'entry'
}
],
'#babel/react',
'#babel/preset-flow'
];
const plugins = [
'#babel/plugin-transform-flow-strip-types',
'#babel/plugin-proposal-class-properties',
'#babel/transform-runtime',
'add-module-exports',
];
return {
presets,
plugins
};
};
I don't know what I can do anymore. My code is so full because with the most basic settings I was getting every error possible. I'm also running a basic addition test which looks like that:
const functions = require('./functions');
test('Adds 2+2 to equal 4', ()=> {
expect(functions.add(2,2)).toBe(4);
});
which works just fine.
EDIT:
I redid TransformIgnorePatterns like so:
"transformIgnorePatterns": [
"node_modules/(?!(jest-)?react-native|react-navigation|#react-native-community|#react-navigation/.*)"
],
And the Error is still this:
● Test suite failed to run
TypeError: Cannot read property 'createAnimatedComponent' of undefined
at Object.<anonymous> (node_modules/react-native-screens/lib/commonjs/index.js:27:23)
at Object.<anonymous> (node_modules/react-navigation-tabs/lib/commonjs/navigators/createBottomTabNavigator.tsx:10:1)
can you try this:
"transformIgnorePatterns": [
"node_modules/(?!(jest-)?react-native|react-navigation|#react-native-community|#react-navigation/.*)"
],
I had Jest tests working under Quasar version 0.14. Currently some simple tests and all snapshot-tests pass but for some tests I keep getting:
1.
console.error node_modules/vue/dist/vue.common.js:593
[Vue warn]: Error in config.errorHandler: "TypeError: Cannot read property 'form' of undefined"
and 2:
console.error node_modules/vue/dist/vue.common.js:1743
TypeError: Cannot read property 'getters' of undefined
and 3:
console.error node_modules/vue/dist/vue.common.js:593
[Vue warn]: Unknown custom element: <q-page-sticky> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
1 and 2 seem to relate to Jest not recognizing a $v.form and the vuex store within the components.
Any suggestions/ best practices how to get this working? I followed along this, and have these settings:
.babelrc:
{
"presets": [
[ "env", {"modules": false} ],
"stage-2"
],
"plugins": ["transform-runtime"],
"comments": false,
"env": {
"test": {
"presets": [
[
"env",
{
"targets": {
"node": "current"
}
}
]
],
"plugins": [
[
"module-resolver",
{
"root": [
"./src"
],
"alias": {
"quasar": "quasar-framework/dist/quasar.mat.esm.js",
"^vue$": "vue/dist/vue.common.js"
}
}
]
]
}
}
}
within package.json:
"jest": {
"testMatch": [
"<rootDir>/src/**/?(*.)(spec).js?(x)"
],
"testPathIgnorePatterns": [
"<rootDir>/src/e2e/"
],
"moduleNameMapper": {
"src/components/([^\\.]*).vue$": "<rootDir>/src/components/$1.vue",
"src/components/([^\\.]*)$": "<rootDir>/src/components/$1.js",
"^vue$": "vue/dist/vue.common.js",
"src/([^\\.]*)$": "<rootDir>/src/$1.js",
"src/([^\\.]*).vue$": "<rootDir>/src/$1.vue",
"(.*)/(.*).vue$": "$1/$2.vue",
"(.*)/(.*)/(.*).vue$": "$1/$2/$3.vue"
},
"moduleFileExtensions": [
"js",
"json",
"vue"
],
"collectCoverageFrom": [
"**/*.{vue}"
],
"coverageDirectory": "<rootDir>/src/components/coverage",
"transformIgnorePatterns": [
"node_modules/core-js",
"node_modules/babel-runtime",
"node_modules/lodash",
"node_modules/vue"
],
"transform": {
"^.+\\.js$": "<rootDir>/node_modules/babel-jest",
".*\\.(vue)$": "<rootDir>/node_modules/vue-jest"
},
"snapshotSerializers": [
"<rootDir>/node_modules/jest-serializer-vue"
]
},
1. The Problem
Your 3rd error occurred because Jest doesn't know what a <q-page-sticky> is. You have to tell it explicitly.
[Vue warn]: Unknown custom element: <q-page-sticky> - did you register the component correctly? For recursive components, make sure to provide the "name" option.
2. The Solution
Its as simple as telling Vue what 'Vuex' is, or what 'vue-router' is. You are probably already familiar with this. The only difference is that we have to use localVue here in the testing environment.
import { shallowMount, createLocalVue } from "#vue/test-utils";
import MyComponent from "#/components/MyComponent";
// I see that you already alias "quasar" in your .babelrc,
// otherwise replace "quasar" with "quasar-framework/dist/quasar.mat.esm.js"
import Quasar, { q-page-sticky } from "quasar";
// or if you are using a lot of Quasar components then do
// import Quasar, * as All from "quasar";
describe("Something Something", () => {
const localVue = createLocalVue();
localVue.use(Quasar, { components: ["q-page-sticky"]});
// or if you are using a lot of Quasar components then do
// localVue.use(Quasar, { components: All, directives: All, plugins: All });
const wrapper = shallowMount(MyComponent, {
localVue,
});
it("works", () => {
expect(wrapper.isVueInstance()).toBe(true);
});
})
3. Reference
The above is a general solution and can be used not just with Quasar framework. You can checkout the following official vue-test-util docs for more information.
Using with Vue Router
Using with Vuex
I had the same warnings (1 and 2). For me, it was using the wrong mount. I used Vue's mount function instead of the one in #vue/test-utils. I don't have the explanation why it works now, but that was it for me.
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
...
}