Тестирование Mock Asyn c Deta Fetching в компонентах React с использованием useEffect и useState - PullRequest
1 голос
/ 18 февраля 2020

У меня есть компонент, который выбирает некоторые данные в useEffect и устанавливает состояние с ответом, используя функции useState. Это похоже на довольно идиоматический паттерн c, но мне не очень повезло, когда я понял, как его протестировать. В этом случае QuarantineApi.getQuarantinedFileLogs возвращает обещание, которое разрешается в массив данных, которые мне нужны. и это то, что я хотел бы высмеять; Базовая реализация (ax ios или fetch) не должна иметь значения.

import React, {useEffect, useState} from 'react'
import {FormGroup, Input, Label, Table} from 'reactstrap'
import {QuarantinedFileLog} from '../QuarantinedFileLog'
import {DeleteQuarantinedFileButton} from './DeleteQuarantinedFileButton'
import {DownloadQuarantinedFileButton} from './DownloadQuarantinedFileButton'
import {UploadQuarantinedFileButton} from './UploadQuarantinedFileButton'
import QuarantineApi from '../../../api/QuarantineApi'
// @ts-ignore
import {GMTLoadingIndicator} from '@gmt/coreui-react'
interface IQuarantinedFilesListProps {
}
export const QuarantinedFilesList = (props: IQuarantinedFilesListProps) => {
  const {getQuarantinedFileLogs} = QuarantineApi
  const [loading, setLoading] = useState(true)
  const [quarantinedFiles, setQuarantinedFiles] = useState<QuarantinedFileLog[]>([])
  const [quarantineServiceError, setQuarantineServiceError] = useState<string|null>(null)
  useEffect(() => {
    getQuarantinedFileLogs().then(
      (returnedQuarantinedFileLogs) => {
        setQuarantinedFiles(returnedQuarantinedFileLogs)
        setLoading(false)
      }
    ).catch(
      error => {
        setQuarantineServiceError(`There was a problem getting quarantined files ${error}`)
        setLoading(false)
      }
    )
  }, [getQuarantinedFileLogs])
  return (
    <>
      {quarantineServiceError && (
        <div className="alert alert-danger" role="alert">
          {quarantineServiceError}
        </div>
      )}
      {loading && <GMTLoadingIndicator />}
      {!loading && !quarantinedFiles.length && (
        <p>No quarantined files</p>
      )}
      {!loading && !!quarantinedFiles.length && (
        <Table>
          <thead>
          <tr>
            <th></th>
            <th>Filename</th>
            <th>Time</th>
            <th>Error</th>
            <th>Actions</th>
          </tr>
          </thead>
          <tbody>
          {quarantinedFiles.map(quarantinedFileLog => {
            return (
              <tr key={quarantinedFileLog.id}>
                <td>
                  <FormGroup check>
                    <Input type="checkbox" name="check" id="exampleCheck" />
                  </FormGroup>
                </td>
                <td>
                  <Label for="exampleCheck" check>{quarantinedFileLog.fileName}</Label>
                </td>
                <td>Date time</td>
                <td>{quarantinedFileLog.errorReason}</td>
                <td>
                  <DeleteQuarantinedFileButton
                    fileName={quarantinedFileLog.fileName}
                  />
                  <span className="ml-2">
                <DownloadQuarantinedFileButton />
              </span>
                  <span className="ml-2">
                <UploadQuarantinedFileButton />
              </span>
                </td>
              </tr>
            )
          })}
          </tbody>
        </Table>
      )}
    </>
  )
}

Это самый близкий пример, который я нашел к тому, что я пытаюсь выполнить sh здесь (адаптированный к моему коду) из этого сообщения переполнения стека ):

import renderer, { act } from 'react-test-renderer'
import {QuarantinedFilesList} from '../QuarantinedFilesList'
import React from 'react'
import {QuarantinedFileLog} from '../QuarantinedFileLog'
import QuarantineApi from '../../../api/QuarantineApi'

describe('QuarantinedFilesList', () => {
    it('renders correctly', async () => {
        const quarantinedFileLogs: QuarantinedFileLog[] = [
            {
                id: 1,
                fileName: 'file 1',
                errorReason: 'error 1',
                queueName: 'queue 1'
            },
            {
                id: 2,
                fileName: 'file 2',
                errorReason: 'error 2',
                queueName: 'queue 2'
            },
            {
                id: 3,
                fileName: 'file 3',
                errorReason: 'error 3',
                queueName: 'queue 3'
            }
        ]

        const quarantineApiSpy = jest.spyOn(QuarantineApi, 'getQuarantinedFileLogs')
            .mockResolvedValueOnce(quarantinedFileLogs)

        let component

        await act(async () => {
            component = renderer.create(<QuarantinedFilesList />)
        })

        expect(quarantineApiSpy).toBeCalled()
        expect(component.toJSON()).toMatchSnapshot()
    })
})

Я получаю ошибку TypeError: Cannot read property 'get' of undefined из другого места приложения, которая не произойдет, если я не высмеиваю ответ .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...