Jest - unexpected identifier - Component testing w Jest react-native - reactjs

I keep getting this error when trying to test a button component. I have changed Jest's config settings here and there but nothing has worked, can anyone tell me the answer so I can stop pulling my hair out?
I am using expo to demo the app, the problem seems to lie within the font that it's trying to render on the nav button, Jest/React doesn't understand it.
The failure:
FAIL tests/Components/NavigationButton.test.js
● Test suite failed to run
C:\..\node_modules\#expo\vector-icons\Zocial.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){import Zocial from './build/Zocial';
^^^^^^
SyntaxError: Unexpected identifier
at ScriptTransformer._transformAndBuildScript (node_modules/#jest/transform/build/ScriptTransformer.js:537:17)
at ScriptTransformer.transform (node_modules/#jest/transform/build/ScriptTransformer.js:579:25)
at Object.<anonymous> (node_modules/react-native-elements/src/helpers/getIconType.js:1:1)
NavigationButton.js:
import React from "react";
import { StyleSheet } from "react-native";
import { Button } from "react-native-elements";
import Icon from "react-native-vector-icons/FontAwesome";
import { withNavigation } from 'react-navigation';
const NavigationButton =(props) => {
return (
<Button data-test="nav_button"
icon={<Icon name={props.icon} size={30} color="white" style={styles.iconStyle} />}
raised
color="white"
buttonStyle={styles.button}
title={props.title}onPress={() => props.navigation.navigate(props.navName)}
/>
);
};
const styles = StyleSheet.create({
button: {
minWidth:150,
alignSelf:'center',
},
iconStyle:{
marginHorizontal:10
}
});
export default withNavigation(NavigationButton);
NavigationButton.test.js:
/**
* #format
*/
import 'react-native';
import React from 'react';
import { shallow } from 'enzyme';
import { findByTestAtt } from '../../Utils/test_utils';
import NavigationButton from '../../src/Components/NavigationButton'
// Note: this is just for use with Jest snapshot testing
// and comes packaged with react-native init project.
// You do not need this if using Enzyme 'toMatchSnapshot' etc.
import renderer from 'react-test-renderer';
// setup for shallow rendering component, saves having to do it in every test in this file
const setup = (props = {}) => {
const component = shallow(<NavigationButton {...props} />);
return component;
};
describe('NavigationButton tests: ', () => {
let component;
beforeEach(() => {
component = setup();
});
it('Button renders correctly: ', () => {
console.log(component.debug());
const wrapper = findByTestAtt(component, 'nav_button');
expect(wrapper.length).toBe(1);
});
});

Using the jest-expo preset solved the problem for me. The documentation explains it well: https://www.npmjs.com/package/jest-expo. The issue seemed to be that the import keyword wasn't being transformed, I'm not clear on why but it came up in an issue here: https://github.com/expo/expo/issues/5296

Related

Jest encountered an unexpected token with SwiperJs

I am creating some snapshot testing with jest. It gives me error with SwiperJs.
In my test i just want to have snapshot that renders component. I also have a single feature component which renders a feature comes from static data. Its test is passing without problem.
When i run test it gives me that eror.
SyntaxError: Unexpected token 'export'
> 2 | import { Swiper, SwiperSlide } from 'swiper/react';
Features.jsx
import { Link } from 'react-router-dom';
import { Swiper, SwiperSlide } from 'swiper/react';
import { Pagination } from 'swiper';
import featuresData from '../../data/featuresData';
import Feature from './Feature';
import illustration from '../../assets/features-illustration.svg';
import star from '../../assets/star.svg';
const Features = () => {
return (
////rest of the component
<Swiper
pagination={{
clickable: true,
}}
modules={[Pagination]}
>
///rest of the swiper
)
}
Features.test.jsx:
import renderer from 'react-test-renderer';
import Features from '../Features';
describe('Features', () => {
it('renders correctly', () => {
const tree = renderer.create(<Features />).toJSON();
expect(tree).toMatchSnapshot();
});
});
I installed jest packages with :
yarn add --dev jest babel-jest #babel/preset-env #babel/preset-react react-test-renderer
The solution for me was to introduce the following into my jest configuration file:
module.exports = {
// ...
transformIgnorePatterns: ['node_modules/(?!(swiper|ssr-window))']
}
Depending on your setup this may differ. In my case I'm extending a config provided by a framework, so all we needed was the above, however see here for a more detailed configuration.

Problem testing react component that implement react-leaflet map with jest

I have the following issue when I tried to test a react components that implement the react-leaflet library
C:\digital-booking-ui\node_modules\react-leaflet\lib\index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export { useMap, useMapEvent, useMapEvents } from './hooks.js';
^^^^^^
SyntaxError: Unexpected token 'export'
1 | import React from "react";
2 | import { makeStyles } from "#material-ui/core";
> 3 | import { MapContainer, TileLayer, Marker, Popup, useMap } from "react-leaflet";
| ^
4 |
5 | const Map = () => {
6 | const classes = useStyles();
at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1728:14)
at Object.<anonymous> (src/components/accomodation/Map.js:3:1)
I search the problem on the internet and the recommendations I found don't work for me.
This error happen when I tried to render any component that has a relation with that library, for example, App.test.js
import { render, screen, prettyDOM } from '#testing-library/react';
import '#testing-library/jest-dom/extend-expect'
import App from './App';
import { BrowserRouter } from 'react-router-dom';
import { ThemeProvider } from '#material-ui/core';
import theme from "./theme";
let component = null;
beforeEach(() => {
component = render(
<BrowserRouter>
<ThemeProvider theme={theme}>
<App />
</ThemeProvider>
</BrowserRouter>
);
}
);
test('render App', () => {
expect(component).toBeTruthy();
});
How could I fix this? It seems a problem of Jest not recognizing the export of the components
In your package.json add these lines
"jest": {
"moduleNameMapper": {
"react-leaflet": "<rootDir>/mocks/reactLeafletMock.js"
}
}
Then in a "mocks" folder (or whatever you want) add a reactLeafletMock.js module that return an empty object
module.exports = {}
It should be ok (it worked for me)
You could eventually add "react-leaflet" hooks within the object to avoid other errors from Jest
module.exports = {
useMapEvents: () => {}
}

Using react-testing-library + jest, why is my code coverage so high despite no "expect"?

I'm attempting to up our test coverage in our app and am a bit confused about the combo of react-testing-library + jest and how they determine coverage.
I'm attempting to test one of our app's components using the following:
import React from 'react'
import { BrandColors } from '#components/settings/BrandColors'
import '#testing-library/jest-dom'
import { MockedProvider } from '#apollo/client/testing'
import { SettingsDocument } from '#generated/graphql'
import { render } from '#testing-library/react'
import { getMockResponse, schemaWithMocks } from '#utils/apollo-mocks'
it('shows a skeleton when loading', async () => {
const data = await getMockResponse(schemaWithMocks, SettingsDocument)
const mock = {
request: {
query: SettingsDocument
},
result: { data }
}
const { container } = render(
<MockedProvider mocks={[mock]}>
<BrandColors />
</MockedProvider>
)
})
I've been developing tests while running --watch so I get immediate feedback every time I save. I was surprised to see that what I wrote above immediately gave me 94% coverage on the <BrandColors> component despite no expect assertions.
What gives?

How to set intellisense for react testing library using typescript

I just downloaded Create-React-App which uses react testing library. I do not get intellisense when I use it's methods (Example : toBeInTheDocument) . How to set intellisense ? Do we have any type definitions for RTL?
import React from 'react';
import { render } from '#testing-library/react';
import App from './App';
test('renders learn react link', () => {
const { getByText } = render(<App />);
const linkElement = getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});
You need to import '#testing-library/jest-dom'

Typescript, Jest and i18next: Can't see text in React component

I am testing a React component that uses i18next for internationalization.
The component:
import * as React from "react";
import { t } from "i18next";
export function Hello(_props) {
return <div className="widget-header">
{t("Hello, world!")}
</div>;
}
The test:
import * as React from "react";
import { render } from "enzyme";
import { Hello } from "./hello";
describe("<Hello />", () => {
it("says hi", () => {
let hi = render(<Hello />);
// FAILS!
// Expected "" to contain "Hello"
expect(hi.text()).toContain("Hello");
});
})
My suspicion is that Jest is stubbing i18next.t() to return undefined rather than "Hello, world!", but I am unsure of that.
I have tried to unmock("i18next") without any luck.
How do I write tests for i18next components in Jest?
UPDATE: I was using Typescript as my compiler. It appears that there is a hoisting issue with the loader I use for Typescript (ES6 hoists imports, jest.unmock is not- Babel users have a plugin to handle this).
Not sure why its not working but you can just mock put i18next like this:
jest.mock('i18next', () => ({
t: (i) => i
}))

Resources