reactjs 如何模拟axios调用

daupos2t  于 2023-02-22  发布在  React
关注(0)|答案(1)|浏览(105)

我有一个组件Student组件如下

import axios from 'axios';
import React from 'react';
import { useEffect, useState } from 'react';

function Student(props) {
  const [studentRecord, setStudentRecord] = useState(props.stRecord);
  const [studentSubjects, setStudentSubjects] = useState(null);
  function getStudentSubjects() {
    let apicalladdress = '/studentapi/GetStudentSubjects/' + studentRecord.studentNumber;
    axios.get(apicalladdress).then((result) => {
      setStudentSubjects(result.data);
    });
  }
  useEffect(() => {
    getStudentSubjects();
  }, [studentRecord]);

  return (
    <div>
      <div>{studentRecord.studentNumber}</div>
      <div>{setStudentSubjects[0].subjectName}</div>
    </div>
  );
}

我创建了一个测试,如下所示

import {StudentSubjectsData} from "../globalDataProvider";
import AxiosMock from "axios"

it("make sure student renders",async ()=>{
  const mockStudentSubjects=await Promise.resolve({data: StudentSubjectsData()});
  AxiosMock.get.mockResolvedValue(mockStudentSubjects);
  
  render (<Student stRecord={StudentRecord}/>);
}

但我收到以下错误
错误1。测试中对Student组件的更新未 Package 在第setStudentSubjects(result.data)行的act(...)中;
错误2。对于以下打印行,我收到错误TypeError:无法读取未定义的属性(正在阅读subjectName)

<div>{setStudentSubjects[0].subjectName}</div>

有什么建议请...

qxsslcnc

qxsslcnc1#

我没有看到你是如何模拟axios.get()方法的,我将使用jest.spyOn()来模拟它。
对于第二个错误,studentSubjects状态在第一次渲染时是null,最好给一个空数组而不是null作为它的初始值,另外,你可以使用optional chain来访问该值。
Student.tsx

import axios from 'axios';
import React from 'react';
import { useEffect, useState } from 'react';

export function Student(props) {
  const [studentRecord, setStudentRecord] = useState(props.stRecord);
  const [studentSubjects, setStudentSubjects] = useState<{ subjectName: string }[]>([]);
  function getStudentSubjects() {
    let apicalladdress = '/studentapi/GetStudentSubjects/' + studentRecord.studentNumber;
    axios.get(apicalladdress).then((result) => {
      setStudentSubjects(result.data);
    });
  }
  useEffect(() => {
    getStudentSubjects();
  }, [studentRecord]);

  return (
    <div>
      <div>{studentRecord.studentNumber}</div>
      <div>{studentSubjects[0]?.subjectName}</div>
    </div>
  );
}

Student.test.tsx

import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom';
import axios from 'axios';
import React from 'react';
import { Student } from './Student';

describe('75502126', () => {
  test('should pass', async () => {
    const axioGetSpy = jest.spyOn(axios, 'get').mockResolvedValue({ data: [{ subjectName: 'a' }] });
    render(<Student stRecord={{ studentNumber: 1 }} />);
    expect(await screen.findByText('a')).toBeInTheDocument();
    axioGetSpy.mockRestore();
  });
});

试验结果:

PASS  stackoverflow/75502126/Student.test.tsx (8.98 s)
  75502126
    ✓ should pass (34 ms)

-------------|---------|----------|---------|---------|-------------------
File         | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-------------|---------|----------|---------|---------|-------------------
All files    |     100 |      100 |     100 |     100 |                   
 Student.tsx |     100 |      100 |     100 |     100 |                   
-------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        9.508 s

相关问题