Redux / Ферментное тестирование вложенных компонентов - PullRequest
0 голосов
/ 28 декабря 2018

У меня есть компонент панели навигации с подключением к редуксу, который отображает два подкомпонента.Одной из них является прославленная кнопка (не избыточная), а другая - панель поиска, подключенная к редуксу.

В тесте я хочу отображать кнопку и подтверждать правильное поведение при нажатии.Однако, если я использую shallow(), то он только отображает заполнитель для кнопки, а сама кнопка недоступна для поиска и нажатия.Если я использую mount (), то тест не пройден, так как мой модульный тест использует не-редукционный экспорт для панели навигации, который затем пытается отобразить дочерний компонент панели поиска, который подключен к редуксу - и у него нет хранилища дляпередать вниз.

Использование экспорта без редукции прекрасно подходит для тестирования мелких визуализаций, но что я могу сделать, чтобы иметь возможность проверить мой компонент панели навигации, нажав кнопку - это может быть полностью выполнено только с помощью mount() call?

Проблема, с которой я столкнулся, заключается в следующем тесте: если я использую shallow (), то он не может найти кнопку, имитирующую щелчок, поскольку он отображается только как заполнитель.Если я использую mount (), то он не сможет отобразить компонент <Searchbar />, так как это компонент с подключением к редуксу, и мой тест передает данные вручную без подключенного хранилища.

Есть ли способ настроить навигациюкомпонент бара для передачи реквизита на панель поиска, если магазин не существует?Или только условно глубокую визуализацию определенных компонентов?Я хочу отображать только PanelTileButton, а не панель поиска

Мой компонент панели навигации

interface IControlBarProps {
    includeValidated: boolean, 
    includeValidatedChanged: (includeValidated:boolean) => void,
}

export class ControlBar extends React.Component<IControlBarProps, {}> {
    constructor(props: any) {    
        super(props);                
      }

    public render() {       
        return <div className="Control-bar">
                 <div className="Control-left" >
                    <SearchBar />
                 </div>
                <div className="Control-center" />
                <div className="Control-right">
                    {this.getDashboardButton("IV", "Include Validated", this.props.includeValidated, () => this.props.includeValidatedChanged(!this.props.includeValidated))}
                </div>
            </div>
    }

    private getDashboardButton(key: string, title: string, newValue: boolean, action: (value:boolean) => void)
    {
        return <div className="Control-Bar-Right" key={key}>          
            <PanelTileButton text={title} iswide={false} highlighted={newValue} 
            // tslint:disable
            onClick={() => action(newValue)} />          
        </div>   
    }

}


function mapStateToProps(state: IStoreState) {
    return {
        includeValidated: state.trade.includeValidated
    };
  }    

  const mapDispatchToProps = (dispatch: Dispatch) => {
    return {
        includeValidatedChanged: (includeValidated:boolean) => {
            dispatch(getIncludeValidatedChangedAction(includeValidated))      
        }
    }
  }

export default connect(mapStateToProps, mapDispatchToProps)(ControlBar);

Мой тест

  it('should handle clicking include validated button', () => {
    const mockCallback = jest.fn();
    const wrapper = mount(<ControlBar includeValidated={false} includeValidatedChanged={mockCallback}  />);

    expect(wrapper.find('div.Control-bar').exists()).toEqual(true);
    expect(wrapper.find({highlighted: false}).exists()).toEqual(true);

    const pb = wrapper.find("PanelTileButton").first();
    pb.find('button').simulate('click', {preventDefault() {} });

    expect(mockCallback.mock.calls.length).toBe(1);  
  })

Ответы [ 2 ]

0 голосов
/ 28 декабря 2018

Вы также можете макетировать компоненты , чтобы избежать необходимости постоянно насмехаться над хранилищем редуксов, когда вы предпочитаете использовать shallow

В той же папке, что и SearchBar.tsxсоздайте подпапку с именем __mocks__ и поместите в нее файл с таким же именем SearchBar.tsx (это соглашение), который возвращает минимальный html

import * as React from 'react';

export default function SearchBar() {
    return <div>SearchBar</div>
}

, а затем в ваш тестовый файл

jest.mock('../SearchBar') // this detects the corresponding mock automatically

import { ControlBar } from '../ControlBar';
import { shallow } from 'enzyme';

...

it('should handle clicking include validated button', () => {
    const mockCallback = jest.fn();
    const wrapper = shallow(<ControlBar includeValidated={false} includeValidatedChanged={mockCallback} />);

    ...
 })
...
0 голосов
/ 28 декабря 2018

Для других, ищущих, как это сделать, я, в конце концов, решил эту проблему, обернув свой смонтированный компонент в тег <Provider> и используя redux-mock-store для передачи ложного хранилища дочерним компонентам, которые по крайней мере позволили бы имрендер.

import configureMockStore  from 'redux-mock-store'

  it('should handle clicking include validated button', () => {
    const mockCallback = jest.fn();
    const mockStore = configureMockStore([])(getTestStore());

    const wrapper = mount(<Provider store={mockStore}><ControlBar includeValidated={false} includeValidatedChanged={mockCallback}  /></Provider>);

    expect(wrapper.find('div.Control-bar').exists()).toEqual(true);
    expect(wrapper.find({highlighted: false}).exists()).toEqual(true);

    const pb = wrapper.find("PanelTileButton").first();
    pb.find('button').simulate('click', {preventDefault() {} });

    expect(mockCallback.mock.calls.length).toBe(1);  
  })
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...