React Native 如何测试在调用后异步呈现的组件

yftpprvb  于 2023-02-19  发布在  React
关注(0)|答案(1)|浏览(149)

假设我有一个组件,当异步调用成功返回时,它会加载其内容:

const MyScreen = () => {
  let userData: userDataResponse;
  const [email, setEmail] = useState("");
  const [firstTime, setFirstTime] = useState(true);

  async function localGetUserData() {
    userData = await getUserData();
    setEmail(userData.email);
    setFirstTime(false);
  }

  useEffect(() => {
    localGetUserData();
  }, []);

  if (firstTime) {
    return <Text>Cargando...</Text>;
  }

  return (
    <SafeAreaView style={styles.formStyling}>

当数据可用时,它将设置一个状态变量,以便呈现真实的内容
如果我想测试它,我想我应该模拟getUserData,这样模拟的函数返回模拟的电子邮件,比如{email: a@b.c}
实现这一目标的好办法是什么?

ldfqzlk8

ldfqzlk81#

假设组件设置如下(因为我无法看到整个组件):
myScreenUtils.js

export const getUserData = async () => {
  return Promise.resolve('original implementation')
}

MyScreen.jsx

import { useState, useEffect } from "react";
import { getUserData } from './myScreenUtils.js'

const MyScreen = () => {
  let userData;
  const [email, setEmail] = useState("");
  const [firstTime, setFirstTime] = useState(true);

  async function localGetUserData() {
    userData = await getUserData();
    setEmail(userData.email);
    setFirstTime(false);
  }

  useEffect(() => {
    localGetUserData();
  }, []);

  if (firstTime) {
    return <div>Cargando...</div>;
  }

  return (
    <div>{email}</div>
  )
};

export default MyScreen;

您可以编写以下测试:

import { screen, render, waitFor, waitForElementToBeRemoved } from '@testing-library/react';

import MyScreen from "../MyScreen";
import * as utils from '../myScreenUtils';

describe('MyScreen', () => {
  it('the text is displayed and then removed', async () => {
    jest.spyOn(utils, 'getUserData').mockResolvedValue({ email: 'mocked value' });
    render(<MyScreen />);

    expect(screen.getByText('Cargando...')).toBeInTheDocument();
    await waitForElementToBeRemoved(() => screen.queryByText('Cargando...'))
  })

  it('the text email is fetched and displayed', async () => {
    jest.spyOn(utils, 'getUserData').mockResolvedValue({ email: 'mocked value' });
    render(<MyScreen />);

    await waitFor(() => {
      expect(screen.getByText('mocked value')).toBeInTheDocument()
    })
  })
})

相关问题