gpt4 book ai didi

react-native - 如何通过 enzyme 或 jest with react-native 模拟后退按钮

转载 作者:行者123 更新时间:2023-12-05 03:02:38 25 4
gpt4 key购买 nike

我无法通过使用 enzyme/jest 和 react-native 代码来模拟硬件后退按钮。并且还提到我是使用 react-native 的 Enzyme/Jest 的新手

我点击了以下链接并尝试实现。不幸的是,我无法做到这一点。

How to simulate android back button in react-native test

示例.js,

import React, { Component } from "react";
import {
View,
Text,
BackHandler,
BackAndroid
} from "react-native";

componentWillMount() {
BackHandler.addEventListener('hardwareBackPress', this.handleBackButtonPress);
}

componentWillUnmount() {
BackHandler.removeEventListener('hardwareBackPress', this.handleBackButtonPress);
}

handleBackButtonPress = () => {
return true;
};

示例.test.js,

import 'react-native';
import React from "react";
import mockPressBack from 'react-native';

jest.mock('BackHandler', () => {
return {
addEventListener: mockPressBack
};
});

describe('sample verifies', ()=>{
test('back button press', ()=> {
const wrapper = shallow(<Sample />);
const sampleData = wrapper.instance();
sampleData.componentWillMount();
});
});

实际结果:类型错误:_reactNative.BackHandler.addEventListener 不是函数

预期结果:运行成功。

我在这里被打动了。请帮助我。

谢谢。

最佳答案

实际上,它被推荐用于模拟大多数(如果不是全部)依赖项的单元测试。小东西是mocking适用于整个模块 - 所以它需要 additional efforts如果您需要模拟某些 export 但让另一个保持事件状态。

你只需要模拟 BackHandler 组件。但是如果你写类似的东西

jest.mock('react-native');
// ...

你会得到一个错误提示

BackHandler.addEventListener is not a function

那是因为基础 jest.mock()jest.fn() 模拟函数替换了每个导出。但是 BackHandler 最初不是一个函数,而是一个对象。

因此您需要手动模拟模块为 BackHandler 提供值:

import { BackHandler } from 'react-native'; // it's needed to direct access mocked version

jest.mock('react-native', () => {
BackHandler: {
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
}
});

describe('Sample', () => {
it('binds to BackHandler on mount and clean up on destroy', () => {
const wrapper = shallow(<Sample />);
expect(BackHandler.addEventListener).toHaveBeenCalledWith('hardwareBackPress');
wrapper.unmount();
expect(BackHandler.removeEventListener).toHaveBeenCalledWith('hardwareBackPress');
});

为了模拟hardwareBackPress,我建议采用几种不同的方法:

  1. 使用提供的实际存储回调来模拟 addEventListener/removeEventListener(这种方法很清楚,但需要额外的代码 - 而且它还需要在测试之间进行清理例)

    const callbacks = {};
    function helperTriggerListeners(eventName, event) {
    (callbacks[eventName] || []).forEach(callback => callback(event));
    }

    jest.mock('react-native', () => {
    BackHandler: {
    addEventListener: jest.fn().mockImplementation((eventName, callback) => {
    callbacks[eventName] = callbacks[eventName] || [];
    callbacks[eventName].psuh(callback);
    }),
    removeEventListener: jest.fn().mockImplementation((eventName, callback) => {
    const indexOf = (callbacks[eventName] || []).indexOf(callback);
    if (indexOf != -1) {
    callbacks[eventName] = callbacks[eventName].splice(indexOf, 1);
    }
    }),
    }
    });

    beforeEach(() => {
    // really important to ensure it's clean from data made in older runs
    callbacks = {};
    BackHandler.addEventListener.mockClear();
    BackHandler.removeEventListener.mockClear();
    });

    it('...', () => {
    helperTriggerListeners('hardwareBackPress', { /* mocked event if required */});
    expect(someOtherMockedService.someMethod).toHaveBeenCalled();
  2. 直接从 addEventListener 模拟日志中获取回调:

    beforeEach(() => {
    // really important otherwise you may call callbacks for component already unmounted
    BackHandler.addEventListener.mockClear();
    BackHandler.removeEventListener.mockClear();
    });

    it('reacts on hardwareBackPress', () => {
    const wrapper = shallow(<Sample />);
    BackHandler.addEventListener.mock.calls.forEach(oneCall => {
    if (oneCall[0] === 'hardwareBackPress') oneCall[1]({ /*mocked Event object*/ });
    })
    expect(someOtherMockedService.someMethod).toHaveBeenCalled();

关于react-native - 如何通过 enzyme 或 jest with react-native 模拟后退按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54649576/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com