I am trying to test the below component App.js
. The component is a simple one that sends a GET request using fetch and displays the result.
import React, { useState, useEffect } from "react";
const App = () => {
const [users, setUsers] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
const fetchAllUsers = async () => {
try {
const response = await fetch(
"https://jsonplaceholder.typicode.com/users"
);
const data = await response.json();
setUsers(data);
} catch (err) {
setError("Something went wrong!");
}
};
fetchAllUsers();
}, []);
return (
<>
<h1>List of Users</h1>
{error && <div>{error}</div>}
{users ? (
<ul>
{users.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
) : (
<p>No users found</p>
)}
</>
);
};
export default App;
The below is my App.test.js
. I did this with the help of tutorials.
import { render, screen } from "@testing-library/react";
import { rest } from "msw";
import { setupServer } from "msw/node";
import App from "./App";
const server = setupServer(
rest.get("https://jsonplaceholder.typicode.com/users", (req, res, ctx) => {
res(ctx.json(["Hello World"]));
})
);
beforeAll(() => {
server.listen();
});
afterAll(() => {
server.close();
});
test("empty", async () => {
render(<App />);
expect(screen.getByText("List of Users")).toBeInTheDocument();
await screen.findByText("Hello world");
});
My test case fails with the below details.
Unable to find an element with the text: Hello world. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
Ignored nodes: comments, script, style
<body>
<div>
<h1>
List of Users
</h1>
<ul>
<li>
Leanne Graham
</li>
/*skipping a few lines of HTML*/
<li>
Clementina DuBuque
</li>
</ul>
</div>
</body>
I can see that mocking hasn't happened and the original API is called. Please help me find my mistake.
You forgot to return the res(ctx.json(['Hello World']));
. Otherwise, msw will throw an warning:
[MSW] Expected a mocking resolver function to return a mocked response Object, but got: undefined. Original response is going to be used instead.
e.g.
App.tsx
:
import React, { useState, useEffect } from 'react';
const App = () => {
const [users, setUsers] = useState(null);
const [error, setError] = useState('');
useEffect(() => {
const fetchAllUsers = async () => {
try {
const response = await fetch('https://jsonplaceholder.typicode.com/users');
const data = await response.json();
setUsers(data);
} catch (err) {
setError('Something went wrong!');
}
};
fetchAllUsers();
}, []);
console.log(users);
return (
<>
<h1>List of Users</h1>
{error && <div>{error}</div>}
{users ? <div>{users[0]}</div> : <p>No users found</p>}
</>
);
};
export default App;
App.test.tsx
:
import { render, screen } from '@testing-library/react';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
import App from './App';
import React from 'react';
import '@testing-library/jest-dom';
const server = setupServer(
rest.get('https://jsonplaceholder.typicode.com/users', (req, res, ctx) => {
return res(ctx.json(['Hello World']));
}),
);
beforeAll(() => {
server.listen();
});
afterAll(() => {
server.close();
});
test('empty', async () => {
render(<App />);
expect(screen.getByText('List of Users')).toBeInTheDocument();
expect(await screen.findByText('Hello World')).toBeInTheDocument();
});
jest.config.js
:
module.exports = {
preset: 'ts-jest/presets/js-with-ts',
testEnvironment: 'jsdom',
setupFilesAfterEnv: [
'jest-extended',
'./jest.setup.js'
],
};
jest.setup.js
:
import 'isomorphic-fetch';
Test result:
PASS stackoverflow/76998600/App.test.tsx (6.264 s)
✓ empty (48 ms)
console.log
null
at App (stackoverflow/76998600/App.tsx:20:10)
console.log
[ 'Hello World' ]
at App (stackoverflow/76998600/App.tsx:20:10)
----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 93.75 | 75 | 100 | 93.33 |
App.tsx | 93.75 | 75 | 100 | 93.33 | 14
----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 6.492 s
package version:
"msw": "^0.29.0",
"jest": "^26.6.3",
"@testing-library/react": "^11.2.7",
"@testing-library/jest-dom": "^5.16.5",
"isomorphic-fetch": "^3.0.0",