React-testing-library render function throws syntax error - javascript

I am trying to start using react-testing-library on my project.
Problem is, I can't setup everything properly.
Steps I made:
I installed #testing-library/react and jest-dom as documentation suggests.
I setup jest.config.js:
module.exports = {
setupFilesAfterEnv: [
'#testing-library/react/cleanup-after-each',
],
};
I wrote basic test:
import React from 'react';
import App from '../App';
import {render } from "#testing-library/react";
it('renders without crashing', () => {
const {asFragment} = render(<App/>);
expect(asFragment).toMatchSnapshot();
});
Error I get:
4 |
5 | it('renders without crashing', () => {
> 6 | const {asFragment} = render(<App/>);
| ^
7 | expect(asFragment).toMatchSnapshot();
8 | });
9 |
My packages versions from package.json file:
"#testing-library/react": "^8.0.4",
"jest-dom": "^3.5.0",
"jest": "^24.8.0",
"react": "^16.6.3",
"react-dom": "^16.6.3",
I've tried several things like cleanuping locally not from jest.config.js file to make it work, but nothing seems to work.
Edit: Project was created with CRA. Even though, I tried to configure babel and babel-jest myself as suggested but didn't work.

I can't tell what was the problem here to be honest. I only know it happen when I was switching from enzyme to react-testing-library.
Note: reverting to enzyme didn't work.
However, I can tell what worked. It was CRA-based project, which means I had all babel, webpack and jest configuration hidden from me. I decided to run npm eject only to fix configuration. Yet, after running this command tests started working again.

Related

Why does the stack trace for my jest tests point to the wrong line numbers?

When I run jest tests in my repo containing errors, the stack trace points to the wrong line numbers. This makes it very difficult to debug. For example:
Expected error
● SimpleComponent › renders
ReferenceError: retur is not defined
4 | export const Simple = () => {
5 | const [count, setCount] = useState(0);
> 6 | retur (
| ^
7 | <div>
8 | <p>You clicked {count} times</p>
9 | <button onClick={() => setCount(count + 1)}>Click me</button>
at Simple (src/SimpleComponent.jsx:6:3)
at Object.<anonymous> (tst/SimpleComponentTest.jsx:8:5)
Received error
Note that it's pointing to the wrong line number - 34 instead of 6.
● SimpleComponent › renders
ReferenceError: retur is not defined
at Simple (src/SimpleComponent.jsx:34:3)
at Object.<anonymous> (tst/SimpleComponentTest.jsx:14:23)
My findings
I found that if I comment out the moduleDirectories entry in jest.config.js, then I get the expected error message. I don't understand why moduleDirectories has such an impact though.
However, I want to keep my moduleDirectories.
Question
Why does the stack trace for jest tests point to the wrong line numbers? How can I fix it?
Files
I have uploaded a minimal example in https://github.com/bluprince13/jest-wrong-line-numbers-in-stack-trace
Source
Note that return statement is spelt wrong.
// src/SimpleComponent.jsx
import React, {useState} from "react"
export const Simple = () => {
const [count, setCount] = useState(0);
retur (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
);
};
Test
// tst/SimpleComponentTest.jsx
import { Simple } from "../src/SimpleComponent";
import { render } from "#testing-library/react";
import React from "react";
describe("SimpleComponent", () => {
it("renders", () => {
render(<Simple />);
});
});
.babelrc
{
"presets": [
"#babel/preset-react",
[
"#babel/preset-env"
]
]
}
jest.config.js
module.exports = {
moduleDirectories: [
"<rootDir>/src",
"<rootDir>/tst",
"<rootDir>/node_modules"
],
testMatch: ["**/tst/**/(*)Test.js?(x)", "**/?(*.)(spec|test).js?(x)"],
transform: {
"^.+\\.jsx?$": "babel-jest"
}
};
package.json
{
"scripts": {
"test": "jest --runInBand"
},
"dependencies": {
"react": "^16.14.0",
"react-dom": "^16.14.0",
"snapshot-diff": "^0.6.2"
},
"devDependencies": {
"babel-jest": "^25.2.4",
"#babel/preset-env": "7.x",
"#babel/preset-react": "7.x",
"#testing-library/react": "^9.2.0",
"jest": "^26.6.3"
}
}
Why does the stack trace for jest tests point to the wrong line numbers? How can I fix it?
It has to do with source maps. If those are not correctly generated or processed, the debugger will show the wrong line.
I found three ways how to fix this issue:
Changing <rootDir>/node_modules to node_modules in your
moduleDirectories
Why does this fix the issue?
If <rootDir> is added,
jest or more precisely its underlying module source-map-support uses the source_map module from node_modules/source-map. Which in my case with a fresh install of your example, is 0.7.3. But the source_map_support relies on ^0.6.0. It actually brings the right version under node_modules/source-map-support/source-map. But for some reason with the <rootDir> specified, it can't access it anymore. And that brings us to the second solution.
Downgrade the source-map module to ^0.6.0 by manually including it as a dependency of your project. In that case node_modules/source-map will provide the right version again, but that might break something else, since it is not clear, where this wrong version is originating from.
Upgrade your project dependencies to the newest version.
try npm outdated and you will see, that they are all outdated:
I believe there is a bug, which counts the empty lines as well.
One solution I found from an open issue on Github - remove "<rootDir>/src" from jest.config.js. Is it a must to keep it?

Using jest to test an Angular Library?

Trying to test an Angular 9 library with Jest, and I've installed the dependencies for Jest and Typescript within the local library package.json like this:
"devDependencies": {
"#types/jest": "^25.1.3",
"jest": "^25.1.0",
"ts-jest": "^25.2.1"
},
And also setup jest.config.js like this:
module.exports = {
"roots": [
"<rootDir>/src/"
],
testMatch: [
"**/__tests__/**/*.+(ts|tsx|js)",
"**/?(*.)+(spec|test).+(ts|tsx|js)"
],
"transform": {
"^.+\\.(ts|tsx)$": "ts-jest"
}
}
However it looks as if jest is not running through the ts-jest transform as I'm getting errors like this:
SyntaxError: Unexpected token export
> 1 | import assertString from './util/assertString';
| ^
2 | import toString from './util/toString';```
Figured it out. I'm converting ValidatorJS into a Typescript project using the Angular Package Format, and I forget to change the file name extension on the utilities from .js to .ts, hence Jest was complaining about the import statement.
In case anyone else wants to setup their project to do this type of thing I wrote up a few articles here:
https://medium.com/#ole.ersoy/unit-testing-angular-with-jest-b65888ff33f6
https://medium.com/#ole.ersoy/unit-testing-your-angular-library-project-with-jest-42429a8716eb

Cannot use namespace 'Boom' as a type

I am using hapi for one of my node+typescript project. I am trying to update hapi to the new #hapi/hapi package, due to the deprecation of the "naked" packages. I've changed #types/hapi to #types/hapi__hapi.
As soon as I updated, I started getting the TypeScript error -
node_modules/#types/hapi__hapi/index.d.ts:514:32 - error TS2709: Cannot use namespace 'Boom' as a type.
514 response: ResponseObject | Boom;
~~~~
node_modules/#types/hapi__hapi/index.d.ts:4050:18 - error TS2709: Cannot use namespace 'Boom' as a type.
4050 (Error | Boom) |
~~~~
Found 2 errors.
Here's the dependencies I have in package.json -
{
...
"devDependencies": {
...
"#types/hapi__boom": "7.4.1",
"#types/hapi__hapi": "18.2.5",
"#types/hapi__joi": "16.0.1",
"#types/nock": "10.0.3",
"#typescript-eslint/eslint-plugin": "2.4.0",
"jest": "24.9.0",
"nock": "11.4.0",
"nodemon": "1.19.4",
"prettier": "1.18.2",
"typescript": "3.6.4"
},
"dependencies": {
...
"#hapi/boom": "8.0.1",
"#hapi/hapi": "18.4.0",
"#hapi/joi": "16.1.7",
"axios": "0.19.0",
"axios-retry": "3.1.2"
},
...
}
I checked the node_modules/#types/hapi__hapi/index.d.ts file and it was importing Boom using the following way -
import * as Boom from '#hapi/boom';
When I change it to
import { Boom } from '#hapi/boom';
and it solved the error.
I can't change the index.d.ts file, as it's from #types/hapi__hapi package, but I want to solve this issue. Is there anything I can do to not have this error, such as downgrading to some specific version?
I checked the issues at #hapi/boom and they included types in 7.x release which were breaking typescript build. They removed types from 7.x releases, but put them back in 8.x, and since I was using #hapi/boom 8.0.1, it was conflicting with the existing types.
All the hapi ecosystem is going to include type definitions in them, but other packages are not updated to do it (as far as I could tell), thus the only way to resolve this issue without breaking breaking TypeScript builds is to downgrade #hapi/boom to 7.4.11.
PS: I found out the github issues minutes after posting the question, but I am still open for better answers, if there is one.

"TypeError not a constructor" when upgrading project from Babel v5 to v6+

I've been bashing my head against this brick wall for a day now so it's time to turn to SO for help I think! I'm trying to update a project off babel v5, I'm starting off with this in package.json:
"devDependencies": {
"babel": "^5.8.21",
"test": "mocha --require babel/register",
I've tried to upgrade to babel both v6 and v7 with no success either time. In both cases I end up with TypeError: _application.ApplicationClient is not a constructor when I attempt to run tests that worked fine with v5:
import { ApplicationClient } from '../src/wiotp/sdk/application';
...
let client = new ApplicationClient();
Using v6 as an example, I end up with the following in package.json:
"devDependencies": {
"babel-cli": "^6.0.0",
"babel-core": "^6.0.0",
"babel-preset-env": "^1.7.0",
"mocha": "6.1.4",
"test": "mocha --require babel-core/register --timeout 5000",
and created a .babelrc file (none existed previously):
{
"presets": ["env"]
}
I've read a dozen or more articles trying to understand what is going on here, I've done and undone numerous suggested "fixes" based on Google searches for similar problems, but I'm starting from zero and finding it incredibly hard to get simple plain-English explanation of what the actual problem is for a start, and how babel is supposed to be configured here to resolve it. I'm guessing something that happened by default in v5 needs to be configured somehow in .babelrc now, but /shrugs/ no idea where to go from here now.
babel5 to babel6 branch compare
babel5 to babel7 branch compare
Any pointers for someone struggling to wrap his head around babel, let alone the differences between v5, 6, & 7?
Edit:
src/wiotp/sdk/application/index.js has this:
import { default as ApplicationClient } from './ApplicationClient';
export default {
ApplicationClient
}
Where src/wiotp/sdk/application/ApplicationClient.js has a single class exported (I'm just trying to create an instance of that class in the test code):
export default class ApplicationClient extends BaseClient {
constructor(config) {
src/wiotp/sdk/application/index.js has this:
import { default as ApplicationClient } from './ApplicationClient';
export default {
ApplicationClient
}
This is horrible, and causing your problem. That module does default-export an object literal, instead of just using named exports. It might be a bug and they meant to write either
import { default as ApplicationClient } from './ApplicationClient';
export { ApplicationClient }
or
export { default as ApplicationClient } from './ApplicationClient';
It would recommend to report an issue and provide a patch.
If this is not considered a bug but was done on purpose, you will need to change your code to
import application from '../src/wiotp/sdk/application';
…
let client = new application.ApplicationClient();
// ^^^^^^^^^^^^
or just import it directly from the original module:
import ApplicationClient from '../src/wiotp/sdk/application/ApplicationClient.js';
// ^^^^^^^^^^^^^^^^^^^^^
…
let client = new ApplicationClient();

React Jest example doesn't work

Trying to run the example of Jest testing React code (from https://github.com/facebook/jest/tree/master/examples/react ), I get the following error:
> # test /home/aizquier/jest/examples/react
> jest
Using Jest CLI v0.7.1
FAIL __tests__/CheckboxWithLabel-test.js
● Runtime Error
SyntaxError: /home/aizquier/jest/examples/react/__tests__/CheckboxWithLabel-test.js: Unexpected token (15:6)
npm ERR! Test failed. See above for more details.
The tests fails at line 15 of file CheckboxWithLabel-test.js:
jest.dontMock('../CheckboxWithLabel');
import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-addons-test-utils';
const CheckboxWithLabel = require('../CheckboxWithLabel');
describe('CheckboxWithLabel', function() {
it('changes the text after click', function() {
// Render a checkbox with label in the document
var checkbox = TestUtils.renderIntoDocument(
<CheckboxWithLabel labelOn="On" labelOff="Off" />
);
var checkboxNode = ReactDOM.findDOMNode(checkbox);
// Verify that it's Off by default
expect(checkboxNode.textContent).toEqual('Off');
// Simulate a click and verify that it is now On
TestUtils.Simulate.change(TestUtils.findRenderedDOMComponentWithTag(checkbox, 'input'));
expect(checkboxNode.textContent).toEqual('On');
});
});
apparently the preprocessor to handle .jsx is not working. The package.json is as follows:
{
"dependencies": {
"react": "~0.14.0",
"react-dom": "~0.14.0"
},
"devDependencies": {
"react-addons-test-utils": "~0.14.0",
"babel-jest": "*",
"jest-cli": "*"
},
"scripts": {
"test": "jest"
},
"jest": {
"scriptPreprocessor": "./node_modules/babel-jest",
"unmockedModulePathPatterns": [
"./node_modules/react",
"./node_modules/react-dom",
"./node_modules/react-addons-test-utils",
"./node_modules/fbjs"
]
}
}
My node is v4.2.2 and npm is 3.3.12.
Any ideas??
I was running into the same problem. It looks like this is an issue caused by the recent release of Babel 6. It's being tracked here, and hopefully a fix is added soon!
In the meantime, you can go back to an earlier version of babel-jest in your package.json. For example, try ^5.3.0.
If you are using Babel 6 there are no default transformations so you'll need to add some presets. Not sure if you can do this in 'package.json' but I added the '.babelrc' file with the 'react' and 'es2015' presets and that sorted it. See http://babeljs.io/docs/plugins/preset-react/

Categories

Resources