Как смоделировать кнопку "Назад" с помощью энзима или шутки с реактивной - PullRequest
0 голосов
/ 12 февраля 2019

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

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

Как смоделировать кнопку возврата Android в собственном тесте реакции

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 не является функцией

Ожидаемый результат: Работает успешно.

IЯ поражен здесь.Пожалуйста, помогите мне.

Спасибо.

1 Ответ

0 голосов
/ 13 февраля 2019

На самом деле это рекомендуется для юнит-тестов, которые чаще всего насмехаются, если не все зависимости.Крошечная вещь mocking работает для всего модуля - поэтому ему нужно дополнительные усилия , если вам нужно смоделировать определенный export, но оставить еще один живой.

Вы простонадо издеваться над BackHandler компонентом.Но если вы напишите что-то вроде

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

Вы получите сообщение о том, что

BackHandler.addEventListener не является функцией

Это потому, что base 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 I 'Я бы предложил несколько разных способов:

  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(); 
    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...