Насмешка над функцией компонента React, которая заключена в компоненте Redux Provider - PullRequest
0 голосов
/ 10 сентября 2018

Вот моя ситуация: Я пытаюсь провести модульное тестирование компонента React (TodoList), который ничего не делает для метода Render, кроме сопоставления элементов и их отображения. Он получает элементы (TodoItem) из магазина Redux с помощью MapStateToProps.

Это код JavaScript для компонента TodoList:

class TodoList extends React.Component {
    onRemoveClick = (id) => {
        diContainer.dataLayer.todo.remove(id);
    }

    render() {
        const todos = this.props.todos;
        if(!todos)
            return null;

        return (
            todos.map(todo => (
                <TodoItem key={todo.id} todo={todo} onRemove={this.onRemoveClick} />
            ))    
        );
    }
}

const mapStateToProps = (state) => ({
    todos: state.todos
});

export default connect(mapStateToProps)(TodoList);

Теперь я хочу проверить, что всякий раз, когда вызывается кнопка внутри TodoItem (дочерний объект), вызывается метод делегата onRemoveClick.

Я пытался использовать функцию насмешки, которую обеспечивает Jest, в сочетании с Enzyme. Однако, поскольку TodoList получает свои данные из Redux, я должен окружить мой вызов mount () Enzyme компонентом Provider и смоделировать хранилище.

Вот мой тестовый код:

import React from 'react';
import { mount } from 'enzyme';

import { Provider } from 'react-redux';
import configureStore from 'redux-mock-store';

import TodoList from '../../../../react/components/todo/TodoList';

describe('TodoList component', () => {
    //global arrange
    const storeState = {
       todos: [
                {
                    id: 'testId1',
                    title: 'testTitle1',
                    description: 'testDescription1'
                },
                {
                    id: 'testId2',
                    title: 'testTitle2',
                    description: 'testDescription2'
                },
        ]
    };

    const mockStore = configureStore();
    let store;

    beforeEach(() => {
        store = mockStore(storeState)
    });

    it('Removes a todo from the list if the remove button the todo was pressed', () => {
        //arrange
        //let mockFn = jest.fn();
        //TodoList.prototype.onRemoveClick = mockFn; => tried, doesn't work...

        const component = mount(
            <Provider store={store}>
                <TodoList />
            </Provider>
        );

        //component.instance() => tried working with this, but couldn't find it
        //component.instance().children() => is not the TodoList

        const items = component.find('.todoItem');

        //act
        const button = items.first().find('button');
        button.simulate('click');

        //assert
        //Todo: check function spy here
    });
});

Я прокомментировал некоторые вещи, которые попробовал. Но я не могу получить доступ к компоненту TodoList в моем тестовом коде из-за обертки провайдера ...

Есть какие-нибудь подсказки?

1 Ответ

0 голосов
/ 10 сентября 2018

Исправлено множеством проб и ошибок.Мне удалось получить доступ к TodoList с помощью функции поиска фермента, которая, очевидно, также работает с ComponentNames (а не только с простыми селекторами HTML).

Второй трюк состоял в том, чтобы вызвать forceUpdate () для компонента TodoList AND update ()на родительской обертке.

it('Removes a todo from the list if the remove button on the todo was pressed', () => {
    //arrange
    const component = mount(
        <Provider store={store}>
            <TodoList />
        </Provider>
    );

    const list = component.find('TodoList').instance();
    let mockFn = jest.fn();
    list.onRemoveClick = mockFn;

    list.forceUpdate();
    component.update();

    //act
    const items = component.find('.todoItem');
    const button = items.first().find('button');
    button.simulate('click');

    //assert
    expect(mockFn).toHaveBeenCalled();
    expect(mockFn).toHaveBeenCalledTimes(1);
    expect(mockFn).toHaveBeenCalledWith('testId1');
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...