0

親コンポーネントAppがあり、ボタンがあります。ボタンをクリックするとaxios、投稿を取得するために呼び出され、投稿アイテムがレンダリングされます。Apphas a child componentPostおよびPosthas a child component ListItem。アプリのテスト ファイルで、ボタンをクリックした後に axios が正しく読み込まれることをテストしました。ただし、レンダリングされたコンテンツをテストすることはできません。data-testid:が見つかりませんUnable to find an element by: [data-testid="test-axios-content"]

私は使用しますreact testing library

ここに私のテストファイルがあります:

import React from "react"
import App from "../../App"
import { render, fireEvent, screen, waitFor, act } from "../utils/test-utils"
import axios from "axios"

jest.mock("axios", () => {
    return {
        get: jest.fn()
    }
})

describe("App test", () => {
    afterEach(() => {
        jest.resetAllMocks()
    })
    it("should load and display the data", async () => {
        const { getByTestId } = render(<App />)

        axios.get.mockResolvedValueOnce({
            data: { title: "hello there", body: "abc" }
        })
        await act(async () => {
            fireEvent.click(getByTestId("test-axios-button"))
            expect(axios.get).toHaveBeenCalledTimes(1)
            const testingData = await waitFor(() => getByTestId("test-axios-content"))
            expect(testingData).toHaveTextContent("hello there")
        })
    })
})

最初の axios calltime は正しいですが、私のテストでは testId が見つかりませんtest-axios-content。App.js の子コンポーネントに配置しました。

App.js

...
function App() {
    const [posts, setPosts] = useState([])
    const handleClick= async () => {
        const postsResult = await getPosts()
        setPosts(postsResult.data)
    }
    return (
        <div className="App" data-test="appComponent">
            <button data-testid="test-axios-button" onClick={handleClick}>
                get post from axios
            </button>
            <section>
                <div>Load Posts:</div>
                <Post posts={posts} data-testid="test-axios-content" />
            </section>
        </div>
}
...

API getPost:

import axios from "axios"
export const getPosts = async () => await axios.get("https://jsonplaceholder.typicode.com/posts?_limit=10")

役職:

import ListItem from "../listItem"

const Post= (props) => {
    const posts = props.posts
    return (
        <>
            {posts.length > 0 && (
                <div>
                    {posts.map((post, index) => {
                        const { title, body } = post
                        return <ListItem key={title} title={title} desc={body} />
                    })}
                </div>
            )}
        </>
    )
}

export default Post

リスト項目:

const ListItem = (props) => {
    const { title, desc } = props
    return (
        <div>
            <h2 data-test="title" data-testid="title">
                {title}
            </h2>
            <div data-test="desc" data-testid="desc">
                {desc}
            </div>
        </div>
    )
}

export default ListItem
4

1 に答える 1

1

最初の間違った部分はposts1 つの配列ですが、axios mockでは 1 つのオブジェクトです: { title: "hello there", body: "abc" }. 正しい形式は次のとおりです。[{ title: "hello there", body: "abc" }]

したがって、axios mockテストの部分では、正しいコードは次のとおりです。

axios.get.mockResolvedValueOnce({
    data: [{ title: "hello there", body: "abc" }]
})

2 番目の間違った部分は、 を使用するのではなく、await act最初にトリガー クリックを使用await waitForし、次にコールバックを使用する必要があります。

fireEvent.click(getByTestId("test-axios-button"))
await waitFor(() => {
    expect(axios.get).toHaveBeenCalledTimes(1)
    const renderData = screen.getByText("hello there")
    expect(renderData).toBeInTheDocument()
})

これは最終的なものです:

it("should load and display the data", async () => {
    const { getByTestId } = render(<App />)

    axios.get.mockResolvedValueOnce({
        data: [{ title: "hello there", body: "abc" }]
    })
    fireEvent.click(getByTestId("test-axios-button"))
    await waitFor(() => {
        expect(axios.get).toHaveBeenCalledTimes(1)
        const testingData = await waitFor(() => getByTestId("test-axios-content"))
        expect(testingData).toHaveTextContent("hello there")
    })
})
于 2021-05-14T05:43:28.220 に答える