react测试 (3) Testing Library

Testing Library是一个使用非常方便的测试辅助工具

安装

在脚手架创建的react项目中开箱即用

npm install --save-dev @testing-library/react

组件

一个类似官网的示例

import React, { useState, useReducer } from 'react'
import axios from "axios"
const initState = {
    error: null,
    greet: null
}

function greetReducer(state,action){

    switch (action.type){
        case "SUCCESS": {
            return{
                error: null,
                greeting: action.greeting
            }
        }
        case "ERROR": {
            return{
                error: action.error,
                greeting: null
            }
        }
        default: {
            return state;
        }
    }
}

export default function Fetch({url}) {
    //一个react的useReducer hooks
    const [{error,greeting}, dispatch] = React.useReducer(greetReducer, initState);
    //state hook
    const [buttonClick,setButtonClick] = React.useState(false);
    const [urlState,setUrlState] = React.useState(url);
    
    //请求数据,在这里我们使用msw模拟,但在这里我们不重点介绍
    let fetchGreeting = async ()=>{
        //使用axios获取数据,更新greeting和按钮的状态
        axios.get(urlState).then(response=>{
        
            const { data } = response;
            
            const {greeting} = data;
            
            dispatch({type:"SUCCESS", greeting})     
            
            setButtonClick("/hello" !== urlState)
            
        }).catch(error=>{
        
            dispatch({ type: 'ERROR', error })
            
        })
    };
    
    //改变请求的url,实际使用中不会有这样的操作
    function change(){
        setUrlState("/hello")
    }
    
    //渲染后立刻获取数据
    React.useEffect(()=>{
        fetchGreeting()
    },[urlState])
    //按钮的文本状态
    const buttonText = buttonClick ? "OK" : "Loading";

    return   <div>
        <button onClick={fetchGreeting} disabled={buttonClick}>
            {buttonText}
        </button>
        <button onClick={change} >
            changeUrl
        </button>
        {greeting && <h1 role="heading">{greeting}</h1>}
        {error && <p role="alert">Oops, failed to fetch!</p>}
    </div>
}

测试

import React from "react"
import { render, fireEvent, waitForElement, screen } from '@testing-library/react'
import '@testing-library/jest-dom/extend-expect'
import Fetch from "./Fetch"
import {act} from "react-dom/test-utils";

describe("greeting",()=>{

    test('loads and displays greeting', async () => {
        //准备组件的渲染
        act(()=>{
            render(<Fetch url="/greeting" />)
            //触发按钮事件,实际上不需要,因为我们在useEffect中依旧加载了,但为了测试,这里依然进行触发
            fireEvent.click(screen.getByText('Loading'))
        })

        //等到role为heading元素显示出来时,即当请求成功返回后
        await waitForElement(() => screen.getByRole('heading'))

        //期望role为heading元素的内容为hello there
        expect(screen.getByRole('heading')).toHaveTextContent('hello there')
        //期望第一个按钮的状态为不可用的
        expect(screen.getAllByRole('button')[0]).toBeDisabled()

    })
    
    test("changeUrl", async()=>{

        act(()=>{
            render(<Fetch url="/greeting" />)
            //组件加载后触发文本为changeUrl的按钮,即改变请求的url
            fireEvent.click(screen.getByText('changeUrl'))
        })
        //等到role为heading元素显示出来时
        await waitForElement(() => screen.getByRole('heading'))
        
        //期望role为heading元素的内容为hello world
        expect(screen.getByRole('heading')).toHaveTextContent('hello world')
         //期望第一个按钮的状态为可用的
        expect(screen.getAllByRole('button')[0]).not.toBeDisabled()
    })

})


除开之前介绍的act外,在这个测试用例中我们还用到了React 测试库的render, fireEvent, waitForElement, screen;

render:渲染测试的组件,即可以看做将组件渲染到屏幕上(虚拟的)

screen: 用于获取我们需要的节点,结合render可以很形象的看成从屏幕上获取我们要的东西

fireEvent: 触发事件,相比Test Utilities的buttons[0].dispatchEvent(new MouseEvent(‘click’, {bubbles: true})),这个好用多了

waitForElement:等待某个元素出现后,相似的还有waitForElementToBeRemoved,waitFor等

除开上面介绍的,Testing Library还有很多的很实用的方法,除开用来测试react外,还可以测试原生js写的DOM节点,vue等,如果有需要的话可以到官网查看

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值