我无法通过将React / Jest与react-native代码一起使用来模拟硬件后退按钮。还提到我是反应原生的酶/笑话新手
我点击了以下链接并尝试实现。不幸的是,我无法做到这一点。
How to simulate android back button in react-native test
Sample.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;
};
sample.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();
});
});
实际结果: TypeError:_reactNative.BackHandler.addEventListener不是函数
预期结果: 它运行成功。
我在这里被打中。请帮助我。
谢谢。
答案 0 :(得分:0)
实际上,建议对大多数(如果不是全部)依赖项进行模拟的单元测试。微小的问题是mocking适用于整个模块-因此,如果您需要模拟某些export
但又要保留另一个additional efforts,则需要nuget。
您只需要模拟BackHandler
组件。但是如果你写类似
jest.mock('react-native');
// ...
您会收到一条错误消息
BackHandler.addEventListener不是函数
这是因为基本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
,我建议几种不同的方法:
在提供实际存储回调的情况下模拟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();
直接从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();