42
loading...
This website collects cookies to deliver better user experience
npx create-react-app my-app
App.test.js
module which is a sample to demonstrate how to test a component. It displays how to render a component in a test module, how to query elements in that component and how to do the assertion part.// App.test.js
import { render, screen } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
const linkElement = screen.getByText(/learn react/i);
expect(linkElement).toBeInTheDocument();
});
setupTest.js
in the project. This file is loaded by jest and we can move repeating parts (like importing the common packages for the test modules) from test modules to this one.npm start
in one of them and run the tests npm test
on another one.a
in the test terminal. The App.test.js would be run after that and you must be seeing all tests are passing.PASS src/App.test.js
√ renders learn react link (61 ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 1.407 s
Ran all test suites.
Watch Usage: Press w to show more
RandomUser.js
and corresponding test module RandomUser.spec.js
*.test.js
or *.spec.js
.// RandomUser.spec.js
import RandomUser from './RandomUser';
import { render, screen } from '@testing-library/react';
describe('Random User', () => {
it('has button to load random user', () => {
render(<RandomUser />);
const loadButton = screen.queryByRole('button', {
name: 'Load Random User'
});
expect(loadButton).toBeInTheDocument();
});
});
screen
's functions to query the elements we are looking for. doc● Random User › has button to load random user
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
4 | describe('Random User', () => {
5 | it('has button to load random user', () => {
> 6 | render(<RandomUser />);
| ^
7 | const loadButton = screen.queryByRole('button', {
8 | name: 'Load Random User'
9 | });
// RandomUser.js
export default function RandomUser(){
// lets return button element having the text we are looking for
return <button>Load Random User</button>;
}
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
//
import RandomUser from './RandomUser';
ReactDOM.render(
<React.StrictMode>
// replace <App/> with our component
<RandomUser />
</React.StrictMode>,
document.getElementById('root')
);
npm i axios
{
"results": [
{
"gender": "female",
"name": {
"title": "Miss",
"first": "Jennifer",
"last": "Alvarez"
},
"location": {
//
},
"email": "[email protected]",
"login": {
//
},
"dob": {
"date": "1954-07-01T18:59:36.451Z",
"age": 67
},
"registered": {
"date": "2016-11-17T05:48:39.981Z",
"age": 5
},
"phone": "07-9040-0066",
"cell": "0478-616-061",
"id": {
"name": "TFN",
"value": "531395478"
},
"picture": {
"large": "https://randomuser.me/api/portraits/women/24.jpg",
"medium": "https://randomuser.me/api/portraits/med/women/24.jpg",
"thumbnail": "https://randomuser.me/api/portraits/thumb/women/24.jpg"
},
"nat": "AU"
}
],
"info": {
//
}
}
// we need to import two packages.
// we will mock the
import axios from 'axios';
// and we will use this user-event to click the button.
import userEvent from '@testing-library/user-event';
// this test will be having async/await
it('displays title, first and lastname of loaded user from randomuser.me', async () => {
render(<RandomUser />);
const loadButton = screen.queryByRole('button', {
name: 'Load Random User'
});
// we will click the button but our request must not be going
// to the real server. we can't be sure how that request
// ends up. So we will mock it. Lets make sure we set what
// axios will return.
// lets define the mock function first
// axios get, post ... functions are promise and here
// we will mock success response by mockResolvedValue
// and we will return the axios response object.
// so we put the actual api response into data object here
const mockApiCall = jest.fn().mockResolvedValue({
data: {
results: [
{
name: {
title: 'Miss',
first: 'Jennifer',
last: 'Alvarez'
}
}
]
}
});
// now lets assign this mock function to axios.get
axios.get = mockApiCall;
// then we can click the button
userEvent.click(loadButton);
// and we expect to see this text on screen.
// this is dependent onto async operation to complete
// so to wait that api call to finish, we use this findBy...
const userInfo = await screen.findByText("Miss Jennifer Alvarez");
expect(userInfo).toBeInTheDocument();
});
● Random User › displays title, first and lastname of loaded user from randomuser.me
TestingLibraryElementError: Unable to find an element with the text: Miss Jennifer Alvarez. 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.
// RandomUser.js
// importing axios, we will make api call
import axios from 'axios';
// we need to have a state
import { useState } from 'react';
export default function RandomUser(){
// we have user object in state
const [user, setUser] = useState();
// this function will be handling the api call
const loadRandomUser = async () => {
try {
const response = await axios.get('https://randomuser.me/api')
// updates the user object with the loaded data
setUser(response.data.results[0])
} catch (error) {
}
}
return (
<>
<button onClick={loadRandomUser}>Load Random User</button>
// if we have user, lets display the name
{user && (
<h1>{`${user.name.title} ${user.name.first} ${user.name.last}`}</h1>
)}
</>
);
}
fetch
, then our test needs to be refactored accordingly.npm i -D whatwg-fetch
// RandomUser.spec.js
import 'whatwg-fetch';
// RandomUser.js
const loadRandomUser = async () => {
try {
const response = await fetch('https://randomuser.me/api');
const body = await response.json();
setUser(body.results[0]);
} catch (error) {
}
}
npm i -D msw
// RandomUser.spec.js
// lets import these two functions
import { setupServer } from "msw/node";
import { rest } from "msw";
it('displays title, first and lastname of loaded user from randomuser.me', async () => {
// here we will create a server
const server = setupServer(
// and this server is going to be processing the GET requests
rest.get("https://randomuser.me/api", (req, res, ctx) => {
// and here is the response it is returning back
return res(ctx.status(200), ctx.json({
results: [
{
name: {
title: 'Miss',
first: 'Jennifer',
last: 'Alvarez'
}
}
]
}));
})
);
// then..
server.listen();
// so at this step we have a server
// after this part we don't need to deal with axios or fetch
// in this test function
render(<RandomUser />);
const loadButton = screen.queryByRole('button', {
name: 'Load Random User'
});
userEvent.click(loadButton);
const userInfo = await screen.findByText("Miss Jennifer Alvarez");
expect(userInfo).toBeInTheDocument();
});
const loadRandomUser = async () => {
try {
const response = await axios.get('https://randomuser.me/api')
user = response.data.results[0];
} catch (error) {
}
}