日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

react jest测试_如何使用React测试库和Jest开始测试React应用

發(fā)布時(shí)間:2023/11/29 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 react jest测试_如何使用React测试库和Jest开始测试React应用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

react jest測(cè)試

Testing is often seen as a tedious process. It's extra code you have to write, and in some cases, to be honest, it's not needed. But every developer should know at least the basics of testing. It increases confidence in the products they build, and for most companies, it's a requirement.

測(cè)試通常被視為乏味的過程。 這是您必須編寫的額外代碼,在某些情況下,老實(shí)說,它不是必需的。 但是,每個(gè)開發(fā)人員都應(yīng)該至少了解測(cè)試的基礎(chǔ)知識(shí)。 它提高了他們所制造產(chǎn)品的信心,對(duì)于大多數(shù)公司而言,這是必需的。

In the React world, there is an amazing library called the react-testing-library which helps you test your React Apps more efficiently. You use it with Jest.

在React世界中,有一個(gè)了不起的庫(kù),稱為react-testing-library ,可幫助您更有效地測(cè)試React Apps。 您將其與Jest一起使用。

In this article, we will see the 8 simple steps you can take to start testing your React Apps like a boss.

在本文中,我們將看到您可以像執(zhí)行老板一樣開始測(cè)試React Apps的8個(gè)簡(jiǎn)單步驟。

  • Prerequisites

    先決條件

  • Basics

    基本

  • What is React Testing Library?

    什么是React Testing庫(kù)?

  • 1. How to create a test snapshot?

    1.如何創(chuàng)建測(cè)試快照?

  • 2. Testing DOM elements

    2.測(cè)試DOM元素

  • 3. Testing events

    3.測(cè)試事件

  • 4. Testing asynchronous actions

    4.測(cè)試異步動(dòng)作

  • 5. Testing React Redux

    5.測(cè)試React Redux

  • 6. Testing React Context

    6.測(cè)試React上下文

  • 7. Testing React Router

    7.測(cè)試React Router

  • 8. Testing HTTP Request

    8.測(cè)試HTTP請(qǐng)求

  • Final Thoughts

    最后的想法

  • Next Steps

    下一步

先決條件 (Prerequisites)

This tutorial assumes that you have at least a basic understanding of React. I will focus only on the testing part.

本教程假定您至少對(duì)React有基本的了解。 我將只關(guān)注測(cè)試部分。

And to follow along, you have to clone the project by running in your terminal:

接下來,您必須通過在終端中運(yùn)行來克隆項(xiàng)目:

git clone https://github.com/ibrahima92/prep-react-testing-library-guide

Next, run:

接下來,運(yùn)行:

yarn

Or, if you use NPM:

或者,如果您使用NPM:

npm install

And that's it! Now let's dive into some basics.

就是這樣! 現(xiàn)在讓我們深入一些基礎(chǔ)知識(shí)。

基本 (Basics)

Some key things will be used a lot in this article, and understanding their role can help you with your understanding.

本文將大量使用一些關(guān)鍵內(nèi)容,了解它們的作用可以幫助您理解。

it or test: describes the test itself. It takes as parameters the name of the test and a function that holds the tests.

it or test :描述測(cè)試本身。 它以測(cè)試名稱和保存測(cè)試的函數(shù)為參數(shù)。

expect: the condition that the test needs to pass. It will compare the received parameter to a matcher.

expect :測(cè)試需要通過的條件。 它將接收到的參數(shù)與匹配器進(jìn)行比較。

a matcher: a function that is applied to the expected condition.

a matcher :應(yīng)用于預(yù)期條件的功能。

render: the method used to render a given component.

render :用于呈現(xiàn)給定組件的方法。

import React from 'react' import {render} from '@testing-library/react' import App from './App'it('should take a snapshot', () => {const { asFragment } = render(<App />)expect(asFragment(<App />)).toMatchSnapshot()}) });

As you can see, we describe the test with it, then, use render to display the App component and expect that asFragment(<App />) matches toMatchSnapshot() (the matcher provided by jest-dom).

如您所見,我們使用it描述測(cè)試,然后使用render顯示App組件,并期望asFragment(<App />)與toMatchSnapshot()匹配(由jest-dom提供的匹配器)。

By the way, the render method returns several methods we can use to test our features. We also used destructuring to get the method.

順便說一句, render方法返回了幾種我們可以用來測(cè)試功能的方法。 我們還使用了分解來獲取方法。

That being said, let's move on and learn more about the React Testing Library in the next section.

話雖如此,讓我們繼續(xù)并在下一節(jié)中進(jìn)一步了解React測(cè)試庫(kù)。

什么是React Testing庫(kù)? (What is the React Testing Library?)

The React Testing Library is a very light-weight package created by Kent C. Dodds. It's a replacement for Enzyme and provides light utility functions on top of react-dom and react-dom/test-utils.

React Testing庫(kù)是由Kent C. Dodds創(chuàng)建的非常輕量級(jí)的軟件包。 它是Enzyme的替代品,并在react-dom和react-dom/test-utils之上提供了輕量級(jí)的實(shí)用程序功能。

The React Testing Library is a DOM testing library, which means that instead of dealing with instances of rendered React components, it handles DOM elements and how they behave in front of real users.

React Testing庫(kù)是一個(gè)DOM測(cè)試庫(kù),這意味著它不處理渲染的React組件實(shí)例,而是處理DOM元素以及它們?cè)趯?shí)際用戶面前的行為。

It's a great library, it's (relatively) easy to start using, and it encourages good testing practices. Note – you can also use it without Jest.

這是一個(gè)很棒的庫(kù),(相對(duì))易于使用,并且鼓勵(lì)良好的測(cè)試實(shí)踐。 注意–您也可以在沒有Jest的情況下使用它。

"The more your tests resemble the way your software is used, the more confidence they can give you."

“您的測(cè)試越像軟件使用方式,就越能給您信心。”

So, let's start using it in the next section. By the way, you don't need to install any packages, since create-react-app comes with the library and its dependencies.

因此,讓我們?cè)谙乱徊糠种虚_始使用它。 順便說一句,您不需要安裝任何軟件包,因?yàn)樵搸?kù)及其依賴項(xiàng)附帶了create-react-app 。

1.如何創(chuàng)建測(cè)試快照 (1. How to create a test snapshot)

A snapshot, as the name suggests, allows us to save the snapshot of a given component. It helps a lot when you update or do some refactoring, and want to get or compare the changes.

顧名思義,快照使我們可以保存給定組件的快照。 當(dāng)您更新或進(jìn)行一些重構(gòu),并希望獲取或比較更改時(shí),它會(huì)很有幫助。

Now, let's take a snapshot of the App.js file.

現(xiàn)在,讓我們對(duì)App.js文件進(jìn)行快照。

  • App.test.js

    App.test.js

import React from 'react' import {render, cleanup} from '@testing-library/react' import App from './App'afterEach(cleanup)it('should take a snapshot', () => {const { asFragment } = render(<App />)expect(asFragment(<App />)).toMatchSnapshot()}) });

To take a snapshot, we first have to import render and cleanup. These two methods will be used a lot throughout this article.

要拍攝快照,我們首先必須導(dǎo)入render和cleanup 。 在本文中,將經(jīng)常使用這兩種方法。

render, as you might guess, helps to render a React component. And cleanup is passed as a parameter to afterEach to just clean up everything after each test to avoid memory leaks.

render ,您可能已經(jīng)猜到,有助于呈現(xiàn)一個(gè)作出React的組成部分。 并且將cleanup作為參數(shù)傳遞給afterEach以便在每次測(cè)試后清除所有內(nèi)容,以避免內(nèi)存泄漏。

Next, we can render the App component with render and get back asFragment as a returned value from the method. And finally, make sure that the fragment of the App component matches the snapshot.

接下來,我們可以渲染的應(yīng)用組件render ,并取回asFragment從方法的返回值。 最后,確保App組件的片段與快照匹配。

Now, to run the test, open your terminal and navigate to the root of the project and run the following command:

現(xiàn)在,要運(yùn)行測(cè)試,請(qǐng)打開終端并導(dǎo)航到項(xiàng)目的根目錄,然后運(yùn)行以下命令:

yarn test

Or, if you use npm:

或者,如果您使用npm:

npm test

As a result, it will create a new folder __snapshots__ and a file App.test.js.snap in the src which will look like this:

結(jié)果,它將在src創(chuàng)建一個(gè)新文件夾__snapshots__和一個(gè)App.test.js.snap文件,如下所示:

  • App.test.js.snap

    App.test.js.snap

// Jest Snapshot v1, https://goo.gl/fbAQLPexports[`Take a snapshot should take a snapshot 1`] = ` <DocumentFragment><div class="App"><h1>Testing</h1></div> </DocumentFragment> `;

And if you make another change in App.js, the test will fail, because the snapshot will no longer match the condition. To make it passes, just press u to update it. And you'll have the updated snapshot in App.test.js.snap.

而且,如果您在App.js進(jìn)行其他更改,則測(cè)試將失敗,因?yàn)榭煺諏⒉辉俜蠗l件。 要使其通過,只需按u即可對(duì)其進(jìn)行更新。 并且您將在App.test.js.snap擁有更新的快照。

Now, let's move on and start testing our elements.

現(xiàn)在,讓我們繼續(xù)并開始測(cè)試我們的元素。

2.測(cè)試DOM元素 (2. Testing DOM elements)

To test our DOM elements, we first have to look at the TestElements.js file.

為了測(cè)試我們的DOM元素,我們首先必須查看TestElements.js文件。

  • TestElements.js

    TestElements.js

import React from 'react'const TestElements = () => {const [counter, setCounter] = React.useState(0)return (<><h1 data-testid="counter">{ counter }</h1><button data-testid="button-up" onClick={() => setCounter(counter + 1)}> Up</button><button disabled data-testid="button-down" onClick={() => setCounter(counter - 1)}>Down</button></>)}export default TestElements

Here, the only thing you have to retain is data-testid. It will be used to select these elements from the test file. Now, let's write the unit test:

在這里,您唯一需要保留的就是data-testid 。 它將用于從測(cè)試文件中選擇這些元素。 現(xiàn)在,讓我們編寫單元測(cè)試:

Test if the counter is equal to 0:

測(cè)試計(jì)數(shù)器是否等于0:

TestElements.test.js

TestElements.test.js

import React from 'react'; import { render, cleanup } from '@testing-library/react'; import TestElements from './TestElements'afterEach(cleanup);it('should equal to 0', () => {const { getByTestId } = render(<TestElements />); expect(getByTestId('counter')).toHaveTextContent(0)});

As you can see, the syntax is quite similar to the previous test. The only difference is that we use getByTestId to select the necessary elements (remember the data-testid) and check if it passed the test. In others words, we check if the text content <h1 data-testid="counter">{ counter }</h1> is equal to 0.

如您所見,語法與先前的測(cè)試非常相似。 唯一的區(qū)別是,我們使用getByTestId選擇必要的元素(記住data-testid )并檢查其是否通過了測(cè)試。 換句話說,我們檢查文本內(nèi)容<h1 data-testid="counter">{ counter }</h1>是否等于0。

Test if the buttons are enabled or disabled:

測(cè)試按鈕是啟用還是禁用:

TestElements.test.js (add the following code block to the file)

TestElements.test.js (將以下代碼塊添加到文件中)

it('should be enabled', () => {const { getByTestId } = render(<TestElements />);expect(getByTestId('button-up')).not.toHaveAttribute('disabled')});it('should be disabled', () => {const { getByTestId } = render(<TestElements />); expect(getByTestId('button-down')).toBeDisabled()});

Here, as usual, we use getByTestId to select elements and check for the first test if the button has a disabled attribute. And for the second, if the button is disabled or not.

在這里,與往常一樣,我們使用getByTestId選擇元素并檢查按鈕是否具有disabled屬性的第一次測(cè)試。 第二,按鈕是否被禁用。

And if you save the file or run again in your terminal yarn test, the test will pass.

并且,如果您保存文件或在終端yarn test再次運(yùn)行,該測(cè)試將通過。

Congrats! Your first test has passed!

恭喜! 您的第一個(gè)測(cè)試已通過!

Now, let's learn how to test an event in the next section.

現(xiàn)在,讓我們?cè)谙乱徊糠种袑W(xué)習(xí)如何測(cè)試事件。

3.測(cè)試事件 (3. Testing events)

Before writing our unit tests, let's first check what the TestEvents.js looks like.

在編寫單元測(cè)試之前,讓我們首先檢查一下TestEvents.js外觀。

  • TestEvents.js

    TestEvents.js

import React from 'react'const TestEvents = () => {const [counter, setCounter] = React.useState(0)return (<><h1 data-testid="counter">{ counter }</h1><button data-testid="button-up" onClick={() => setCounter(counter + 1)}> Up</button><button data-testid="button-down" onClick={() => setCounter(counter - 1)}>Down</button></>)}export default TestEvents

Now, let's write the tests.

現(xiàn)在,讓我們編寫測(cè)試。

Test if the counter increments and decrements correctly when we click on buttons:

單擊按鈕時(shí),測(cè)試計(jì)數(shù)器是否正確遞增和遞減:

TestEvents.test.js

TestEvents.test.js

import React from 'react'; import { render, cleanup, fireEvent } from '@testing-library/react'; import TestEvents from './TestEvents'afterEach(cleanup);it('increments counter', () => {const { getByTestId } = render(<TestEvents />); fireEvent.click(getByTestId('button-up'))expect(getByTestId('counter')).toHaveTextContent('1')});it('decrements counter', () => {const { getByTestId } = render(<TestEvents />); fireEvent.click(getByTestId('button-down'))expect(getByTestId('counter')).toHaveTextContent('-1')});

As you can see, these two tests are very similar except the expected text content.

如您所見,除了預(yù)期的文本內(nèi)容之外,這兩個(gè)測(cè)試非常相似。

The first test fires a click event with fireEvent.click() to check if the counter increments to 1 when the button is clicked.

第一個(gè)測(cè)試使用fireEvent.click()觸發(fā)click事件,以檢查單擊按鈕時(shí)計(jì)數(shù)器是否增加為1。

And the second one checks if the counter decrements to -1 when the button is clicked.

第二個(gè)檢查單擊按鈕時(shí)計(jì)數(shù)器是否遞減到-1。

fireEvent has several methods you can use to test events, so feel free to dive into the documentation to learn more.

fireEvent有幾種可用于測(cè)試事件的方法,因此請(qǐng)隨時(shí)閱讀文檔以了解更多信息。

Now that we know how to test events, let's move on and learn in the next section how to deal with asynchronous actions.

現(xiàn)在我們知道了如何測(cè)試事件,讓我們繼續(xù)學(xué)習(xí)下一節(jié)如何處理異步操作。

4.測(cè)試異步動(dòng)作 (4. Testing asynchronous actions)

An asynchronous action is something that can take time to complete. It can be an HTTP request, a timer, and so on.

異步操作需要花費(fèi)一些時(shí)間才能完成。 它可以是HTTP請(qǐng)求,計(jì)時(shí)器等。

Now, let's check the TestAsync.js file.

現(xiàn)在,讓我們檢查一下TestAsync.js文件。

  • TestAsync.js

    TestAsync.js

import React from 'react'const TestAsync = () => {const [counter, setCounter] = React.useState(0)const delayCount = () => (setTimeout(() => {setCounter(counter + 1)}, 500))return (<><h1 data-testid="counter">{ counter }</h1><button data-testid="button-up" onClick={delayCount}> Up</button><button data-testid="button-down" onClick={() => setCounter(counter - 1)}>Down</button></>)}export default TestAsync

Here, we use setTimeout() to delay the incrementing event by 0.5s.

在這里,我們使用setTimeout()將增量事件延遲0.5s。

Test if the counter is incremented after 0.5s:

測(cè)試計(jì)數(shù)器是否在0.5s后遞增:

TestAsync.test.js

TestAsync.test.js

import React from 'react'; import { render, cleanup, fireEvent, waitForElement } from '@testing-library/react'; import TestAsync from './TestAsync'afterEach(cleanup);it('increments counter after 0.5s', async () => {const { getByTestId, getByText } = render(<TestAsync />); fireEvent.click(getByTestId('button-up'))const counter = await waitForElement(() => getByText('1')) expect(counter).toHaveTextContent('1')});

To test the incrementing event, we first have to use async/await to handle the action because, as I said earlier, it takes time to complete.

為了測(cè)試遞增事件,我們首先必須使用async / await來處理該動(dòng)作,因?yàn)檎缥抑八f的,它需要時(shí)間才能完成。

Next, we use a new helper method getByText(). This is similar to getByTestId(), except that getByText() selects the text content instead of id or data-testid.

接下來,我們使用新的輔助方法getByText() 。 這類似于getByTestId() ,除了getByText()選擇文本內(nèi)容而不是id或data-testid。

Now, after clicking to the button, we wait for the counter to be incremented with waitForElement(() => getByText('1')). And once the counter incremented to 1, we can now move to the condition and check if the counter is effectively equal to 1.

現(xiàn)在,單擊按鈕后,我們等待使用waitForElement(() => getByText('1'))來增加計(jì)數(shù)器。 一旦計(jì)數(shù)器增加到1,我們現(xiàn)在可以移至條件并檢查計(jì)數(shù)器是否有效等于1。

That being said, let's now move to more complex test cases.

話雖如此,讓我們現(xiàn)在轉(zhuǎn)到更復(fù)雜的測(cè)試用例。

Are you ready?

你準(zhǔn)備好了嗎?

5.測(cè)試React Redux (5. Testing React Redux)

If you're new to React Redux, this article might help you. Otherwise, let's check what the TestRedux.js looks like.

如果您不熟悉React Redux, 本文可能會(huì)為您提供幫助。 否則,讓我們檢查一下TestRedux.js外觀。

  • TestRedux.js

    TestRedux.js

import React from 'react' import { connect } from 'react-redux'const TestRedux = ({counter, dispatch}) => {const increment = () => dispatch({ type: 'INCREMENT' })const decrement = () => dispatch({ type: 'DECREMENT' })return (<><h1 data-testid="counter">{ counter }</h1><button data-testid="button-up" onClick={increment}>Up</button><button data-testid="button-down" onClick={decrement}>Down</button></>)}export default connect(state => ({ counter: state.count }))(TestRedux)

And for the reducer:

對(duì)于減速器:

  • store/reducer.js

    store/reducer.js

export const initialState = {count: 0,}export function reducer(state = initialState, action) {switch (action.type) {case 'INCREMENT':return {count: state.count + 1,}case 'DECREMENT':return {count: state.count - 1,}default:return state}}

As you can see, there is nothing fancy – it's just a basic Counter Component handled by React Redux.

如您所見,沒有什么花哨的-它只是由React Redux處理的基本計(jì)數(shù)器組件。

Now, let's write the unit tests.

現(xiàn)在,讓我們編寫單元測(cè)試。

Test if the initial state is equal to 0:

測(cè)試初始狀態(tài)是否等于0:

TestRedux.test.js

TestRedux.test.js

import React from 'react' import { createStore } from 'redux' import { Provider } from 'react-redux' import { render, cleanup, fireEvent } from '@testing-library/react'; import { initialState, reducer } from '../store/reducer' import TestRedux from './TestRedux'const renderWithRedux = (component,{ initialState, store = createStore(reducer, initialState) } = {} ) => {return {...render(<Provider store={store}>{component}</Provider>),store,} }afterEach(cleanup);it('checks initial state is equal to 0', () => {const { getByTestId } = renderWithRedux(<TestRedux />)expect(getByTestId('counter')).toHaveTextContent('0')})

There are a couple of things we need to import to test React Redux. And here, we create our own helper function renderWithRedux() to render the component since it will be used several times.

我們需要導(dǎo)入一些內(nèi)容來測(cè)試React Redux。 在這里,我們將創(chuàng)建自己的幫助器函數(shù)renderWithRedux()來呈現(xiàn)組件,因?yàn)樗鼘⒍啻问褂谩?

renderWithRedux() receives as parameters the component to render, the initial state, and the store. If there is no store, it will create a new one, and if it doesn't receive an initial state or a store, it returns an empty object.

renderWithRedux()接收要渲染的組件,初始狀態(tài)和存儲(chǔ)作為參數(shù)。 如果沒有存儲(chǔ),它將創(chuàng)建一個(gè)新存儲(chǔ),如果沒有收到初始狀態(tài)或存儲(chǔ),則將返回一個(gè)空對(duì)象。

Next, we use render() to render the component and pass the store to the Provider.

接下來,我們使用render()渲染組件并將商店傳遞給Provider。

That being said, we can now pass the component TestRedux to renderWithRedux() to test if the counter is equal to 0.

話雖如此,我們現(xiàn)在可以將組件TestRedux傳遞給renderWithRedux()以測(cè)試計(jì)數(shù)器是否等于0 。

Test if the counter increments and decrements correctly:

測(cè)試計(jì)數(shù)器是否正確遞增和遞減:

TestRedux.test.js (add the following code block to the file)

TestRedux.test.js (將以下代碼塊添加到文件中)

it('increments the counter through redux', () => {const { getByTestId } = renderWithRedux(<TestRedux />, {initialState: {count: 5} })fireEvent.click(getByTestId('button-up'))expect(getByTestId('counter')).toHaveTextContent('6') })it('decrements the counter through redux', () => {const { getByTestId} = renderWithRedux(<TestRedux />, {initialState: { count: 100 },})fireEvent.click(getByTestId('button-down'))expect(getByTestId('counter')).toHaveTextContent('99') })

To test the incrementing and decrementing events, we pass an initial state as a second argument to renderWithRedux(). Now, we can click on the buttons and test if the expected result matches the condition or not.

為了測(cè)試遞增和遞減事件,我們將初始狀態(tài)作為第二個(gè)參數(shù)傳遞給renderWithRedux() 。 現(xiàn)在,我們可以單擊按鈕并測(cè)試預(yù)期結(jié)果是否符合條件。

Now, let's move to the next section and introduce React Context.

現(xiàn)在,讓我們進(jìn)入下一部分并介紹React Context。

React Router and Axios will come next – are you still with me?

接下來是React Router和Axios –您還和我在一起嗎?

6.測(cè)試React上下文 (6. Testing React Context)

If you're new to React Context, check out this article first. Otherwise, let's check the TextContext.js file.

如果您不熟悉React Context,請(qǐng)先閱讀本文 。 否則,讓我們檢查TextContext.js文件。

  • TextContext.js

    TextContext.js

import React from "react"export const CounterContext = React.createContext()const CounterProvider = () => {const [counter, setCounter] = React.useState(0)const increment = () => setCounter(counter + 1)const decrement = () => setCounter(counter - 1)return (<CounterContext.Provider value={{ counter, increment, decrement }}><Counter /></CounterContext.Provider>) }export const Counter = () => { const { counter, increment, decrement } = React.useContext(CounterContext) return (<><h1 data-testid="counter">{ counter }</h1><button data-testid="button-up" onClick={increment}> Up</button><button data-testid="button-down" onClick={decrement}>Down</button></>) }export default CounterProvider

Now, the counter state is managed through React Context. Let's write the unit test to check if it behaves as expected.

現(xiàn)在,計(jì)數(shù)器狀態(tài)通過React Context進(jìn)行管理。 讓我們編寫單元測(cè)試以檢查其行為是否符合預(yù)期。

Test if the initial state is equal to 0:

測(cè)試初始狀態(tài)是否等于0:

TextContext.test.js

TextContext.test.js

import React from 'react' import { render, cleanup, fireEvent } from '@testing-library/react' import CounterProvider, { CounterContext, Counter } from './TestContext'const renderWithContext = (component) => {return {...render(<CounterProvider value={CounterContext}>{component}</CounterProvider>)} }afterEach(cleanup);it('checks if initial state is equal to 0', () => {const { getByTestId } = renderWithContext(<Counter />)expect(getByTestId('counter')).toHaveTextContent('0') })

As in the previous section with React Redux, here we use the same approach, by creating a helper function renderWithContext() to render the component. But this time, it receives only the component as a parameter. And to create a new context, we pass CounterContext to the Provider.

與上一節(jié)關(guān)于React Redux的部分一樣,這里我們通過創(chuàng)建一個(gè)輔助函數(shù)renderWithContext()來渲染組件,使用相同的方法。 但是這一次,它僅接收組件作為參數(shù)。 為了創(chuàng)建新的上下文,我們將CounterContext傳遞給Provider。

Now, we can test if the counter is initially equal to 0 or not.

現(xiàn)在,我們可以測(cè)試計(jì)數(shù)器最初是否等于0。

Test if the counter increments and decrements correctly:

測(cè)試計(jì)數(shù)器是否正確遞增和遞減:

TextContext.test.js (add the following code block to the file)

TextContext.test.js (將以下代碼塊添加到文件中)

it('increments the counter', () => {const { getByTestId } = renderWithContext(<Counter />)fireEvent.click(getByTestId('button-up'))expect(getByTestId('counter')).toHaveTextContent('1')})it('decrements the counter', () => {const { getByTestId} = renderWithContext(<Counter />)fireEvent.click(getByTestId('button-down'))expect(getByTestId('counter')).toHaveTextContent('-1')})

As you can see, here we fire a click event to test if the counter increments correctly to 1 and decrements to -1.

如您所見,這里我們觸發(fā)一個(gè)click事件,以測(cè)試計(jì)數(shù)器是否正確地增加到1并減少到-1。

That being said, we can now move to the next section and introduce React Router.

話雖如此,我們現(xiàn)在可以進(jìn)入下一部分并介紹React Router。

7.測(cè)試React Router (7. Testing React Router)

If you want to dive into React Router, this article might help you. Otherwise, let's check the TestRouter.js file.

如果您想深入研究React Router, 這篇文章可能會(huì)對(duì)您有所幫助。 否則,讓我們檢查TestRouter.js文件。

  • TestRouter.js

    TestRouter.js

import React from 'react' import { Link, Route, Switch, useParams } from 'react-router-dom'const About = () => <h1>About page</h1>const Home = () => <h1>Home page</h1>const Contact = () => {const { name } = useParams()return <h1 data-testid="contact-name">{name}</h1> }const TestRouter = () => {const name = 'John Doe'return (<><nav data-testid="navbar"><Link data-testid="home-link" to="/">Home</Link><Link data-testid="about-link" to="/about">About</Link><Link data-testid="contact-link" to={`/contact/${name}`}>Contact</Link></nav><Switch><Route exact path="/" component={Home} /><Route path="/about" component={About} /><Route path="/about:name" component={Contact} /></Switch></>) }export default TestRouter

Here, we have some components to render when navigating the Home page.

在這里,我們有一些導(dǎo)航主頁時(shí)要呈現(xiàn)的組件。

Now, let's write the tests:

現(xiàn)在,讓我們編寫測(cè)試:

  • TestRouter.test.js

    TestRouter.test.js

import React from 'react' import { Router } from 'react-router-dom' import { render, fireEvent } from '@testing-library/react' import { createMemoryHistory } from 'history' import TestRouter from './TestRouter'const renderWithRouter = (component) => {const history = createMemoryHistory()return { ...render (<Router history={history}>{component}</Router>)} }it('should render the home page', () => {const { container, getByTestId } = renderWithRouter(<TestRouter />) const navbar = getByTestId('navbar')const link = getByTestId('home-link')expect(container.innerHTML).toMatch('Home page')expect(navbar).toContainElement(link) })

To test React Router, we have to first have a navigation history to start with. Therefore we use createMemoryHistory() to well as the name guessed to create a navigation history.

要測(cè)試React Router,我們首先必須有一個(gè)導(dǎo)航歷史記錄。 因此,我們使用createMemoryHistory()以及猜測(cè)的名稱來創(chuàng)建導(dǎo)航歷史記錄。

Next, we use our helper function renderWithRouter() to render the component and pass history to the Router component. With that, we can now test if the page loaded at the start is the Home page or not. And if the navigation bar is loaded with the expected links.

接下來,我們使用輔助函數(shù)renderWithRouter()渲染組件并將history傳遞給Router組件。 這樣,我們現(xiàn)在可以測(cè)試在開始時(shí)加載的頁面是否是主頁。 并在導(dǎo)航欄中加載預(yù)期的鏈接。

Test if it navigates to other pages with the parameters when we click on links:

單擊鏈接時(shí),測(cè)試是否使用參數(shù)導(dǎo)航到其他頁面:

TestRouter.test.js (add the following code block to the file)

TestRouter.test.js (將以下代碼塊添加到文件中)

it('should navigate to the about page', ()=> {const { container, getByTestId } = renderWithRouter(<TestRouter />) fireEvent.click(getByTestId('about-link'))expect(container.innerHTML).toMatch('About page') })it('should navigate to the contact page with the params', ()=> {const { container, getByTestId } = renderWithRouter(<TestRouter />) fireEvent.click(getByTestId('contact-link'))expect(container.innerHTML).toMatch('John Doe') })

Now, to check if the navigation works, we have to fire a click event on the navigation links.

現(xiàn)在,要檢查導(dǎo)航是否有效,我們必須在導(dǎo)航鏈接上觸發(fā)click事件。

For the first test, we check if the content is equal to the text in the About Page, and for the second, we test the routing params and check if it passed correctly.

對(duì)于第一個(gè)測(cè)試,我們檢查內(nèi)容是否與“關(guān)于頁面”中的文本相等,對(duì)于第二個(gè)測(cè)試,我們測(cè)試路由參數(shù)并檢查其是否正確傳遞。

We can now move to the final section and learn how to test an Axios request.

現(xiàn)在,我們可以轉(zhuǎn)到最后一節(jié),學(xué)習(xí)如何測(cè)試Axios請(qǐng)求。

We're almost done!

我們快完成了!

8.測(cè)試HTTP請(qǐng)求 (8. Testing HTTP Request)

As usual, let's first see what the TextAxios.js file looks like.

與往常一樣,讓我們??首先看一下TextAxios.js文件的外觀。

  • TextAxios.js

    TextAxios.js

import React from 'react' import axios from 'axios'const TestAxios = ({ url }) => {const [data, setData] = React.useState()const fetchData = async () => {const response = await axios.get(url)setData(response.data.greeting) } return (<><button onClick={fetchData} data-testid="fetch-data">Load Data</button>{ data ?<div data-testid="show-data">{data}</div>:<h1 data-testid="loading">Loading...</h1>}</>) }export default TestAxios

As you can see here, we have a simple component that has a button to make a request. And if the data is not available, it will display a loading message.

如您在這里看到的,我們有一個(gè)簡(jiǎn)單的組件,該組件帶有一個(gè)用于發(fā)出請(qǐng)求的按鈕。 并且如果數(shù)據(jù)不可用,它將顯示一條加載消息。

Now, let's write the tests.

現(xiàn)在,讓我們編寫測(cè)試。

Test if the data are fetched and displayed correctly:

測(cè)試是否已正確提取和顯示數(shù)據(jù):

TextAxios.test.js

TextAxios.test.js

import React from 'react' import { render, waitForElement, fireEvent } from '@testing-library/react' import axiosMock from 'axios' import TestAxios from './TestAxios'jest.mock('axios')it('should display a loading text', () => {const { getByTestId } = render(<TestAxios />)expect(getByTestId('loading')).toHaveTextContent('Loading...') })it('should load and display the data', async () => {const url = '/greeting'const { getByTestId } = render(<TestAxios url={url} />)axiosMock.get.mockResolvedValueOnce({data: { greeting: 'hello there' },})fireEvent.click(getByTestId('fetch-data'))const greetingData = await waitForElement(() => getByTestId('show-data'))expect(axiosMock.get).toHaveBeenCalledTimes(1)expect(axiosMock.get).toHaveBeenCalledWith(url)expect(greetingData).toHaveTextContent('hello there') })

This test case is a bit different because we have to deal with an HTTP request. And to do that, we have to mock an axios request with the help of jest.mock('axios').

這個(gè)測(cè)試用例有些不同,因?yàn)槲覀儽仨毺幚硪粋€(gè)HTTP請(qǐng)求。 為此,我們必須借助jest.mock('axios')模擬axios請(qǐng)求。

Now, we can use axiosMock and apply a get() method to it. Finally we will use the Jest function mockResolvedValueOnce() to pass the mocked data as a parameter.

現(xiàn)在,我們可以使用axiosMock并對(duì)其應(yīng)用一個(gè)get()方法。 最后,我們將使用Jest函數(shù)mockResolvedValueOnce()來傳遞mockResolvedValueOnce()數(shù)據(jù)作為參數(shù)。

With that, now for the second test we can click to the button to fetch the data and use async/await to resolve it. And now we have to test 3 things:

這樣,現(xiàn)在對(duì)于第二個(gè)測(cè)試,我們可以單擊按鈕來獲取數(shù)據(jù)并使用async / await來解決它。 現(xiàn)在我們必須測(cè)試3件事:

  • If the HTTP request has been done correctly

    如果HTTP請(qǐng)求已正確完成
  • If the HTTP request has been done with the url

    如果HTTP請(qǐng)求已通過url完成

  • If the data fetched matches the expectation.

    如果獲取的數(shù)據(jù)符合期望。
  • And for the first test, we just check if the loading message is displayed when we have no data to show.

    對(duì)于第一個(gè)測(cè)試,我們只檢查沒有數(shù)據(jù)要顯示時(shí)是否顯示加載消息。

    That being said, we're now done with the 8 simple steps to start testing your React Apps.

    話雖如此,我們現(xiàn)在已經(jīng)完成了8個(gè)簡(jiǎn)單步驟來開始測(cè)試React Apps。

    Don't be scared to test anymore.

    不要害怕測(cè)試了。

    最后的想法 (Final Thoughts)

    The React Testing Library is a great package for testing React Apps. It gives us access to jest-dom matchers we can use to test our components more efficiently and with good practices. Hopefully this article was useful, and it will help you build robust React apps in the future.

    React Testing庫(kù)是用于測(cè)試React Apps的出色軟件包。 它使我們能夠訪問jest-dom匹配器,我們可以使用它們來更有效地并通過良好實(shí)踐來測(cè)試我們的組件。 希望本文對(duì)您有所幫助,并在將來幫助您構(gòu)建功能強(qiáng)大的React應(yīng)用。

    You can find the finished project here

    您可以在這里找到完成的項(xiàng)目

    Thanks for reading it!

    感謝您閱讀!

    Read more articles ?- ?Subscribe to my newsletter ? - ? Follow me on twitter

    文章 - 訂閱我的新聞通訊 - 在Twitter上關(guān)注我

    You can read other articles like this on my blog.

    您可以在我的博客上閱讀其他類似的文章 。

    下一步 (Next Steps)

    React Testing Library docs

    React Testing庫(kù)文檔

    React Testing Library Cheatsheet

    React測(cè)試庫(kù)備忘單

    Jest DOM matchers cheatsheet

    笑話DOM匹配器備忘單

    Jest Docs

    笑話文檔

    翻譯自: https://www.freecodecamp.org/news/8-simple-steps-to-start-testing-react-apps-using-react-testing-library-and-jest/

    react jest測(cè)試

    總結(jié)

    以上是生活随笔為你收集整理的react jest测试_如何使用React测试库和Jest开始测试React应用的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。