如何测试平台与Jest的反应?

时间:2020-07-06 10:23:11

标签: react-native jestjs enzyme

如果平台是ios,我想显示苹果按钮。该按钮在ios模拟器中正确显示。但是我对测试平台感到困惑。 我已经尝试过模拟该平台,但是默认情况下该平台在第一时间将为ios(您可以看到该图像)。

这是我的组件。

import React, { useState, useEffect } from 'react'
import { ScrollView, StatusBar, Platform, View, Text, Linking, SafeAreaView } from 'react-native'
import Header from './components/Header'
import Form from './components/Form'
import ButtonFull from '../../../__global__/button/buttonFull'
import styles from './styles/StyleLogin'
import color from '../../../__global__/styles/themes/colorThemes'
const LoginScreen = () => {

  const showAppleButton = () => {
    console.log('Platform ', Platform.OS)
    if (Platform.OS === 'ios') {
      console.log('Platform OS ', Platform.OS)
      console.log('Platform Version ', Platform.Version)
      const version = Platform.Version ? Platform.Version.split('.')[0] : 0
      if (version >= 13) {
        return (
          <View style={styles.containerButton}>
            <ButtonFull
              accessibilityLabel={'appleButton'}
              isDisabled={false}
              buttonColor={color.black}
              onPress={() => loginWithApple()}
              title={'Apple ID'}
            />
          </View>
        )
      } else {
        return false
      }
    } else {
      return false
    }
  }

  return (
    <ScrollView>
      <StatusBar
        translucent
        backgroundColor="transparent"
        barStyle="light-content"
      />
      <Header />
      <Form
        phoneNumber={phoneNumber}
        changePhoneNumber={(value) => changePhoneNumber(value)}
        focus={focus}
        setFocus={(value) => setFocus(value)}
        loginSubmit={() => loginSubmit()}
        error={error}
        fullFilled={fullFilled}
        submited={submited}
        setSubmited={(value) => setSubmited(value)}
        sendOtp={() => sendOtp()} />
      {showAppleButton()}
    </ScrollView>
  )
}

export default LoginScreen

测试文件

import React from 'react'
import { configure, shallow } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'
import LoginScreen from '../index'
import renderer from 'react-test-renderer'
import { fireEvent, render, waitFor } from 'react-native-testing-library'
import '@testing-library/jest-native/extend-expect'
import { Provider } from 'react-redux'
import reducers from '../../../../redux/store'
import { createStore } from 'redux'
import { Platform } from 'react-native'
jest.mock('@react-navigation/native', () => ({
  useNavigation: component => component,
}))

describe('Login screen', () => {
  const mockPlatform = (OS, Version) => {
    jest.resetModules()
    jest.doMock('react-native/Libraries/Utilities/Platform', () => ({
      OS,
      select: config => config[OS],
      Version,
    }))
  };

  const store = createStore(reducers)
  configure({ adapter: new Adapter() })
  const wrapper = shallow(<Provider store={store}><LoginScreen /></Provider>)
  const rendered = renderer.create(<Provider store={store}><LoginScreen /></Provider>)

  it('renders correctly', () => {
    expect(rendered.toJSON()).toBeTruthy()
  })

  it('should render the header component', () => {
    expect(wrapper.find('Header').exists())
  })

  it('should render the form component', () => {
    expect(wrapper.find('Form').exists())
  })

  it('should render the button social media', () => {
    mockPlatform('android', '15.0.1')
    console.log('Apple Button ', wrapper.find('[accessibilityLabel="appleButton"]').exists())
  })
})

在此图中,平台将是第一次ios。我不知道为什么。 Test Result

1 个答案:

答案 0 :(得分:1)

依靠react-native/Libraries/Utilities/Platform之类的模块内部结构并不安全。 Platform是从react-native导入的,最好在此模块上进行模拟。

jest.doMock不会影响在顶层导入的模块。为了使模拟生效,依赖于模拟模块的整个层次结构都需要使用require在本地重新导入。

在这种情况下,不需要这样做,因为Platform被称为对象,因此可以模拟其属性。模拟需要知道哪些属性可以模拟为函数:

let originalOS;

beforeEach(() => {
  originalOS = Platform.OS;
});

afterEach(() => {
  Platform.OS = originalOS;
  jest.restoreAllMocks();
});

it('should mock Platform', () => {
  jest.spyOn(Platform, 'select').mockReturnValue('android');
  jest.spyOn(Platform, 'Version', 'get').mockReturnValue('15.0.1')
  Platform.OS = 'android';
  ...
});