Шутить и шпионить за импортированной асинхронной функцией - PullRequest
1 голос
/ 20 марта 2019

Я пытаюсь понять, как смоделировать импортированную функцию свойств в Jest

Это мой компонент AboutScreen.js

import React from 'react';
import { Constants, WebBrowser } from 'expo';
import { View, Text } from 'react-native';

const AboutScreen = () => { 
return (
  <View>
    <Text testId={"t-and-c"} onPress={() => WebBrowser.openBrowserAsync('tcUrl')}>
Terms & conditions
    </Text>
  </View>
  );
};


export default AboutScreen;

Мой тест в AboutScreen.test.js выглядит следующим образом

import React from 'react';
import { shallow } from 'enzyme';
import config from '../../config';
import AboutScreen from '../AboutScreen';
import { Constants, WebBrowser } from 'expo';
const { termsAndConditionsUrl, privacyPolicyUrl } = config;

jest.mock('expo', () => ({
  Constants: {
    manifest: {
        version: '0.0.1',
        releaseChannel: 'PROD',
    },
  WebBrowser: {
    openBrowserAsync: jest.fn()
    }
  },
 }));

it('click on terms and conditions link', () => {
   const mock = jest.spyOn(WebBrowser, 'openBrowserAsync'); 
   mock.mockImplementation(() => Promise.resolve());
   // above statement return 'Cannot spyOn on a primitive value; undefined given' 
   // WebBrowser.openBrowserAsync = jest.fn(); --> This returns `WebBroser undefined
   const wrapper = shallow(<AboutScreen />);
   wrapper.find({ testId: 't-and-c' }).simulate('click');
   expect(mock).lastCalledWith('abc');
   // expect(WebBrowser.openBrowserAsync).toHaveBeenCalledWith('tcUrl);
});

Мне удалось смоделировать Constants.manifest.version, но я не смог понять, как смоделировать функцию в объекте 'Browser`.

1 Ответ

0 голосов
/ 20 марта 2019

Вы близки.


Вы в настоящее время насмехаетесь над WebBrowser, чтобы стать свойством внутри из Constants, поэтому его необходимо удалить следующим образом:

jest.mock('expo', () => ({
  Constants: {
    manifest: {
      version: '0.0.1',
      releaseChannel: 'PROD',
    }
  },
  WebBrowser: {
    openBrowserAsync: jest.fn()
  }
}));

Другая проблема заключается в том, как simulate работает при использовании shallow.Из раздела Common Gotchas в документе:

Даже если имя подразумевает, что это имитирует фактическое событие, .simulate() фактически нацеливается на опору компонента на основе событияВы даете это.Например, .simulate('click') фактически получит реквизит onClick и вызовет его.

... и поскольку ваш компонент не имеет свойства onClick, вызов .simulate('click') завершается выполнениемНичего.

В этом посте от разработчика Airbnb рекомендуется напрямую вызывать реквизиты и избегать simulate.

Вы можете вызвать onPress, вызвав реквизит прямо так:

wrapper.find({ testId: 't-and-c' }).props().onPress();

Итак, все вместе рабочий тест выглядит так:

import React from 'react';
import { shallow } from 'enzyme';
import config from '../../config';
import AboutScreen from '../AboutScreen';
import { Constants, WebBrowser } from 'expo';
const { termsAndConditionsUrl, privacyPolicyUrl } = config;

jest.mock('expo', () => ({
  Constants: {
    manifest: {
      version: '0.0.1',
      releaseChannel: 'PROD',
    }
  },
  WebBrowser: {
    openBrowserAsync: jest.fn()
  }
}));

it('click on terms and conditions link', () => {
  const mock = jest.spyOn(WebBrowser, 'openBrowserAsync');
  mock.mockImplementation(() => Promise.resolve());

  const wrapper = shallow(<AboutScreen />);

  wrapper.find({ testId: 't-and-c' }).props().onPress();
  expect(mock).toHaveBeenCalledWith('tcUrl'); // Success!
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...