Мокинг функции компонента React, заключенной в компонент Redux Provider

Вот моя ситуация: Я пытаюсь провести модульное тестирование компонента 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.

Я пробовал использовать функцию mocking, которую предоставляет Jest, вместе с Enzyme. Однако, поскольку TodoList получает свои данные из Redux, я должен окружить мой вызов Enzyme mount () компонентом 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 в моем тестовом коде из-за оболочки Provider ...

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

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
3
0
893
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Второй трюк заключался в вызове forceUpdate () в компоненте TodoList И 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');
});

Другие вопросы по теме