Nano Hash - криптовалюты, майнинг, программирование

Как выполнить модульное тестирование действия Redux в компоненте внутри подключенного компонента Redux с помощью Jest

Я использую jest и enzyme для модульного тестирования своего приложения React, и я борюсь с тестированием подключенных компонентов.

У меня есть простой компонент, который имеет следующую логику:

class LoginPage extends React.Component {

    componentDidMount() {
        if (!this.props.reduxReducer.appBootstrapped) {
                this.props.dispatch(ReduxActions.fadeOutAndRemoveSplashScreen(500));
        }
    }

    render() {
        return (
            <div data-page="login-page" >
                <div>This is the login page.</div>
            </div>
        );
    }
}

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

export default connect(mapStateToProps, null)(LoginPage);

Итак, это компонент, который отображает элемент <div />, содержащий некоторый текст, но важная часть, которую я хочу протестировать, заключается в том, что при монтировании компонента отправляется действие для скрытия экрана-заставки. Я хочу, чтобы это происходило только тогда, когда приложение не загружается.

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

describe("[LoginPage Component]", () => {
    it("Renders without a problem.", () => {
        // Act.
        const wrapper = mount(
            <LoginPage store={ reduxStore } />
        );

        // Assert.
        expect(wrapper.find("div[data-page=\"login-page\"]").length).toBe(1);
    });
});

Свойство reduxStore — это мой фактический редукционный магазин, созданный с помощью следующего кода:

const reduxStore = createStore(
    combineReducers(
        {
            reduxReducer
        }
    )
);

Теперь, как я могу протестировать метод componentDidMount() и, в частности, проверить, что действие redux fadeOutAndRemoveSplashScreen() вызывается только тогда, когда приложение еще не загружено.

Я действительно думаю, что мне нужно издеваться над моим магазином редуксов, однако я новичок в этом и не знаю, как начать, поэтому пример будет высоко оценен.

Если есть какие-либо другие мысли о моей реализации, не стесняйтесь дать несколько советов.

С уважением


Ответы:


1

Я бы не стал использовать необработанный метод dispatch для отправки действия. Я бы использовал mapDispatchToProps. Это делает ваше действие доступным непосредственно в реквизитах вашего компонента — здесь мы используем разрушение ES6 как сокращение в методе connect.

Тогда вместо того, чтобы издеваться над хранилищем избыточности, я бы просто протестировал ваш компонент без него. Попробуйте добавить экспорт в class (первая строка). Например:

export class LoginPage extends React.Component {

    componentDidMount() {
        if (!this.props.reduxReducer.appBootstrapped) {
          // make sure that you are using this.props.action() not
          // just the action(), which is not connected to redux
          this.props.fadeOutAndRemoveSplashScreen(500);
        }
    }

    render() {
        return (
            <div data-page="login-page" >
                <div>This is the login page.</div>
            </div>
        );
    }
}

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

export default connect(mapStateToProps, {
  fadeOutAndRemoveSplashScreen: ReduxActions.fadeOutAndRemoveSplashScreen
})(LoginPage);

Затем в вашем тесте вместо импорта подключенного компонента импортируйте класс:

import ConnectedLoginPage, { LoginPage } from '/path/to/component';

Затем просто передайте LoginPage любые реквизиты, которые вы хотите протестировать. Поэтому мы установим для вашего appBooststrapped значение false, а затем передаем действие как sinon шпиона:

const spy = sinon.spy();
const reduxReducer = {
  appBootstrapped: false, // or true
}
const wrapper = mount(
    <LoginPage reduxReducer={reduxReducer} fadeOutAndRemoveSplashScreen={spy} />
);

// test that the spy was called
expect(spy.callCount).to.equal(1);

Это делает тест намного проще, и, что более важно, вы тестируете поведение компонента, а не Redux.

26.04.2017
  • Спасибо, именно тот ответ, который я искал. 26.04.2017
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

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

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..