Как протестировать снимки с помощью Jest и нового React lazy 16.6 API - PullRequest
0 голосов
/ 07 ноября 2018

Мне нужно импортировать компоненты с новым React lazy API (16.6).

import React, {PureComponent, lazy} from 'react';

const Component1 = lazy(() => import('./Component1'));
const Component2 = lazy(() => import('./Component2'));

class CustomComponent extends PureComponent {
  ...
  render() {

  return (
    <div>
      <Component1 />
      <Component2 />
    </div>
  );
 }
}

В своих тестах я делаю снимки этого компонента. Это очень простой тест:

import { create } from 'react-test-renderer';

const tree = await create(<CustomComponent />).toJSON();

expect(tree).toMatchSnapshot();

В логах тест не пройден с этой ошибкой:

A React component suspended while rendering, but no fallback UI was specified.

Add a <Suspense fallback=...> component higher in the tree to provide a loading indicator or placeholder to display.

Должен ли я в каждом тестовом наборе набирать <Suspense>...?

it('should show the component', async () => {
  const component = await create(
    <React.Suspense fallback={<div>loading</div>}>
     <CustomComponent /> 
    </React.Suspense> 
  ); 
  const tree = component.toJSON(); 

  expect(tree).toMatchSnapshot(); 

};

Если я это сделаю, то в снимке я вижу только компонент fallback.

+ Array [ + <div> + loading + </div>, + ]

Итак, какой лучший способ сделать это?

Ответы [ 2 ]

0 голосов
/ 05 июля 2019

У меня была похожая проблема, когда я хотел провести тестирование моментальных снимков вложенных компонентов, и один из них был загружен с отложенной загрузкой. Вложенность выглядела примерно так:

SalesContainer -> SalesAreaCard -> SalesCard -> AreaMap

Где SalesContainer - верхний компонент. AreaMap -компонент загружается с помощью SalesCard с использованием React lazy и Suspense. Для большинства разработчиков тесты прошли локально с AreaMap, представленным в снимке. Но тесты всегда с треском проваливались в Jenkins CI с AreaMap, который никогда не отображался. Слабовато, если не сказать больше.

Чтобы пройти тесты, я добавил магическую линию await testRenderer.getInstance().loadingPromise; к тестам. Это пример теста:

import React from 'react';
import renderer from 'react-test-renderer';
import wait from 'waait';
import SalesContainer from './index';

describe('<SalesContainer />', () => {
it('should render correctly', async () => {
    const testRenderer = renderer.create(
      <SalesContainer />
    );
    await wait(0);
    await testRenderer.getInstance().loadingPromise;
    expect(testRenderer).toMatchSnapshot();
  });
});
0 голосов
/ 11 ноября 2018

Нужно ли мне в каждом тестовом наборе набирать <Suspense>?

Да, компонент Suspense необходим для ленивой загрузки дочерних компонентов, особенно для обеспечения откатов и для согласования, когда доступны ленивые компоненты.

Экспорт Component1 и Component2 в CustomComponent, чтобы их можно было импортировать в тестах.

import React, {PureComponent, lazy} from 'react';

export const Component1 = lazy(() => import('./Component1'));
export const Component2 = lazy(() => import('./Component2'));

export default class CustomComponent extends PureComponent {
  //...
}

Помните, что лениво загруженные компоненты похожи на обещания. Импортируйте их в тест и дождитесь их разрешения, прежде чем проверять соответствие снимка.

import { create } from 'react-test-renderer';
import React, {Suspense} from 'react';
import CustomComponent, {Component1, Component2} from './LazyComponent';

describe('CustomComponent', () => {
  it('rendered lazily', async()=> {
    const root = create(
      <Suspense fallback={<div>loading...</div>}>
        <CustomComponent/>
      </Suspense>
    );

    await Component1;
    await Component2;
    expect(root).toMatchSnapshot();
  })
})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...