Как поверхностно протестировать компонент без подключения к редуксу, использующий перехваты - PullRequest
1 голос
/ 07 ноября 2019

У меня проблема с моими модульными тестами в jest / энзиме в моем проекте ReactJS, я преобразовал свои компоненты в ES6 и использовал зацепки для подключения моего редукса к хранилищу редуктора. Однако после добавления изменений в использование хуков в этом компоненте модульный тест для него был прерван, и я потратил несколько дней, пытаясь выяснить, почему этот тест больше не будет выполнять поверхностный рендеринг, поскольку полное монтирование будет работать нормально.

DemoPage.js

import React  from 'react';
import { useSelector, useDispatch} from 'react-redux';
import * as actions from '../../actions/demoPageActions';
import DemoPageForm from '../demoApp/DemoPageForm';
import {compose} from "recompose";
import {withStyles} from "@material-ui/core";

const styles = theme => ({});

export const DemoPage = () => {
  const demoState = useSelector(state => state.demoPage);
  const dispatch = useDispatch();

  const saveSomething = () => {
    dispatch(actions.saveSomething(demoState));
  };

  const calculateSomething = e => {
    dispatch(actions.calculateSomething(demoState, e.target.name, e.target.value));
  };

  return (
    <DemoPageForm
      onSaveClick={saveSomething}
      onChange={calculateSomething}
      demoState={demoState}
    />
  );
};

export default compose(withStyles(styles))(DemoPage);

DemoPage.spec.js

import React from "react";
import { shallow } from "enzyme";
import {DemoPage} from "./DemoPage";
import DemoPageForm from "../demoApp/DemoPageForm";

describe("<DemoPage />", () => {
  it("should contain <DemoPageForm />", () => {
    const wrapper = shallow(
      <DemoPage/>
    );
    expect(wrapper.find(DemoPageForm).length).toEqual(1);
  });
});

, что приводит к следующей ошибке

 <DemoPage /> › should contain <DemoPageForm />

    Invariant Violation: could not find react-redux context value; please ensure the component is wrapped in a <Provider>

       9 | 
      10 | export const DemoPage = () => {
    > 11 |   const demoState = useSelector(state => state.demoPage);
         |                     ^
      12 |   const dispatch = useDispatch();
      13 | 
      14 |   const saveSomething = () => {

Это очень запутанно, так как все равно должно бытьтестировать неподключенный компонент, однако я считаю, что проблема возникает с помощью ловушек для useSelector, поэтому после прочтения примерно 30-40 страниц информации об этом мне еще предстоит найти решение, и самое близкое, что у меня есть, это использовать mount, который работает нормально, однако яЯ предпочел бы мелкое для этого тестирования, вот код и результат, когда завернут в провайдера с mockstore

describe("<DemoPage />", () => {
  const mockStore = configureMockStore()
  const store = mockStore(returnInitialState());

  it("should contain <DemoPageForm />", () => {
    const wrapper = shallow(
      <Provider store={store}>
        <DemoPage
          store={store}
        />
      </Provider>
    );

    console.log(wrapper.dive().debug())

    expect(wrapper.find(DemoPageForm).length).toEqual(1);
  });
});
   console.log src/components/containers/DemoPage.spec.js:23
      <DemoPage store={{...}} />

  ● <DemoPage /> › should contain <DemoPageForm />

    expect(received).toEqual(expected) // deep equality

    Expected: 1
    Received: 0

      23 |     console.log(wrapper.dive().debug())
      24 | 
    > 25 |     expect(wrapper.find(DemoPageForm).length).toEqual(1);
         |                                               ^
      26 |   });
      27 | });

Если кто-нибудь знает, как это можно решить, это было бы чрезвычайно полезно. Приветствия

Ответы [ 2 ]

0 голосов
/ 15 ноября 2019

У меня были проблемы с работой shallow рендеринга с ферментом. В настоящее время фермент не поддерживает полностью реагирующие крючки в неглубоких визуализированных тестируемых компонентахВам нужно будет использовать mount на данный момент. Вы можете отслеживать прогресс на странице проблемы, связанной с их github в выпуске # 1938

Если вы хотите попробовать использовать мелкое, у вас есть доступ к довольно небольшому количеству функциональности в настоящее время. Попробуйте обновить enzyme-adapter-react-16 до версии 1.15.1 или новее, чтобы устранить некоторые наиболее явные проблемы. У него определенно все еще есть проблемы по состоянию на 12.11.19, когда я в последний раз пытался добавить его, но все лучше и лучше, когда они работают над проблемами совместимости.

0 голосов
/ 11 ноября 2019

Ваш тест не пройден именно потому, что shallow просто отображает один уровень дерева DOM. Таким образом, вы получаете только <Provider /> часть дерева, но никогда не достигаете <DemoPage />. Это также объясняет, почему mount работает нормально.

Вам, вероятно, следует прочитать doc ™ ️ более внимательно, прежде чем переходить в режим безумия Google. Обратите внимание, что функция shallow(node, options) принимает второй аргумент. И там он предоставляет два способа взаимодействия с контекстом React:

  1. вы либо передаете объект Context непосредственно в options.context
  2. , либо вы можете передать компонент поставщика, передающий этот контекст, в options.wrappingComponent.

Пример кода для options.wrappingComponent использование:

import { Provider } from 'react-redux';
import { Router } from 'react-router';
import store from './my/app/store';
import mockStore from './my/app/mockStore';

function MyProvider(props) {
  const { children, customStore } = props;

  return (
    <Provider store={customStore || store}>
      <Router>
        {children}
      </Router>
    </Provider>
  );
}
MyProvider.propTypes = {
  children: PropTypes.node,
  customStore: PropTypes.shape({}),
};
MyProvider.defaultProps = {
  children: null,
  customStore: null,
};

const wrapper = shallow(<MyComponent />, {
  wrappingComponent: MyProvider,
});
const provider = wrapper.getWrappingComponent();
provider.setProps({ customStore: mockStore });

Отказ от ответственности: приведенный выше код бесстыдно копируется напрямую с фермента doc ссылка здесь .

...