簡體   English   中英

用玩笑測試反應組件

[英]Testing react component with jest

我正在關注關於反應的測試文檔,數據獲取部分: https : //reactjs.org/docs/testing-recipes.html#data-fetching

它使用 fetch 來獲取數據。 我用 axios 嘗試過同樣的方法,但出現以下錯誤:

TypeError: Cannot read property 'textContent' of null
    > 43 |   expect(container.querySelector(".uid").textContent).toBe(fakeUser.userId);
         |          ^
      44 |   expect(container.querySelector(".id").textContent).toBe(fakeUser.id);
      45 |   expect(container.querySelector(".title").textContent).toBe(fakeUser.title);

我認為錯誤是因為 jest 沒有等待 axios 獲取數據然后重新渲染組件。 我不知道等待元素。

這是 User.js

import React from "react";
import axios from "axios";

class User extends React.Component {
  state = {
    user: null
  };

  componentDidMount() {
    this.fetchUserData("1");
  }

  async fetchUserData(id) {
    const response = await axios.get(
      `https://jsonplaceholder.typicode.com/albums/${id}`
    );
    const user = await response.data;

    this.setState({
      user
    });
  }

  render() {
    const { user } = this.state;
    if (!user) {
      return <div>loading...</div>;
    }
    return (
      <div>
        <div className="uid">{user.userId}</div>
        <div className="id">{user.id}</div>
        <div className="title">{user.title}</div>
      </div>
    );
  }
}

export default User;

這是 User.test.js

import React from "react";
import { render, unmountComponentAtNode } from "react-dom";
import { act } from "react-dom/test-utils";
import User from "./User";
import axios from "axios";

let container = null;
jest.mock("axios");

beforeEach(() => {
  // setup a DOM element as a render target
  container = document.createElement("div");
  document.body.appendChild(container);
});

afterEach(() => {
  // cleanup on exiting
  unmountComponentAtNode(container);
  container.remove();
  container = null;
});

it("renders user data", async () => {
  const fakeUser = {
    userId: "1",
    id: "1",
    title: "quidem molestiae enim"
  };

  axios.get.mockResolvedValue(fakeUser);
  // Use the asynchronous version of act to apply resolved promises
  await act(async () => {
    render(<User id="1" />, container);
  });

  expect(container.querySelector(".uid").textContent).toBe(fakeUser.userId);
  expect(container.querySelector(".id").textContent).toBe(fakeUser.id);
  expect(container.querySelector(".title").textContent).toBe(fakeUser.title);
});

嗯,我解決了這個問題。 解決方案是模擬axios並使用mockImplementation模擬實現響應

import React from "react";
import { render, unmountComponentAtNode } from "react-dom";
import { act } from "react-dom/test-utils";
import User from "./User";
import axios from "axios";

let container = null;
jest.mock("axios");
beforeEach(() => {
  // setup a DOM element as a render target
  container = document.createElement("div");
  document.body.appendChild(container);
});

afterEach(() => {
  // cleanup on exiting
  unmountComponentAtNode(container);
  container.remove();
  container = null;
});

it("renders user data", async () => {
  const fakeUser = {
    userId: "1",
    id: "1",
    title: "quidem molestiae enim"
  };

  axios.get.mockImplementation(() =>
    Promise.resolve({
      data: fakeUser
    })
  );
  // Use the asynchronous version of act to apply resolved promises
  await act(async () => {
    render(<User id="1" />, container);
  });

  expect(container.querySelector(".uid").textContent).toBe(fakeUser.userId);
  expect(container.querySelector(".id").textContent).toBe(fakeUser.id);
  expect(container.querySelector(".title").textContent).toBe(fakeUser.title);
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM