开玩笑地模拟和监视导入的异步函数 [英] Jest mock and spy on an imported async function

查看:798
本文介绍了开玩笑地模拟和监视导入的异步函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图弄清楚如何在Jest中模拟导入的属性函数

I am trying to figure out how to mock an imported properties function in 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中的测试如下所示

My test in AboutScreen.test.js looks like below

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`对象中的功能.

I was able to mock the Constants.manifest.version but unable to figure out how to mock the function within the 'Browser` object.

推荐答案

您已经关闭.

您当前正在嘲笑WebBrowser成为Constants的属性内部,因此需要像这样将其移出:

You are currently mocking WebBrowser to be a property inside of Constants, so that needs to be moved out like this:

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


另一个问题是使用shallowsimulate的工作方式.在文档的常见问题部分:


The other issue is how simulate works when using shallow. From the Common Gotchas section of the doc:

即使名称暗示这将模拟一个实际事件,.simulate()实际上也将根据您提供的事件将组件的prop作为目标.例如,.simulate('click')实际上将获得onClick道具并调用它.

Even though the name would imply this simulates an actual event, .simulate() will in fact target the component's prop based on the event you give it. For example, .simulate('click') will actually get the onClick prop and call it.

...并且由于您的组件没有onClick属性,因此调用.simulate('click')最终无济于事.

...and since your component doesn't have an onClick property calling .simulate('click') ends up doing nothing.

这篇帖子建议直接调用道具,然后避免使用simulate.

This post from an Airbnb dev recommends invoking props directly and avoiding simulate.

您可以通过直接调用prop来调用onPress,如下所示:

You can invoke onPress by calling the prop directly like this:

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


所有的工作测试看起来像这样:


So all together the working test looks like this:

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!
});

这篇关于开玩笑地模拟和监视导入的异步函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆