고차 컴포넌트로 React Native Jest 테스트 설정하기
25421 단어 reactnativejestreacttypescript
SafeAreaProvider - 장치의 안전 영역에만 액세스하도록 하기 위해
ThemeProvider - Styled Components와 같은 것을 사용하여 전체 앱에 테마 컨텍스트를 제공한다고 가정합니다.
Redux - 앱 전체에서 상태를 관리하기 위해
구성 요소가 하나 이상의 고차 구성 요소(HoC)에서 제공하는 것에 부주의하게 의존할 수 있기 때문에 이는 단위 및 통합 테스트를 작성할 때 일이 까다로울 수 있습니다.
Jest 테스트 설정을 단순화하기 위해 테스트별로 필요한 HoC를 쉽게 활용할 수 있도록 몇 가지 도우미 함수를 작성했습니다. 일을 더 단순하게 만드는 것은 개발 시간을 단축하면서 더 많은 테스트를 작성하는 장벽을 낮추는 것을 의미하므로 이것이 큰 승리입니다. 🎉
다음은 Typescript에서 수행할 수 있는 방법의 예입니다. 우리가 사용하는 외부 패키지는 Redux Toolkit, Styled Components 및 React Native Safe Area Context입니다.
// testHelpers.tsx
import * as React from 'react'
import { getDefaultMiddleware } from '@reduxjs/toolkit'
import lodash from 'lodash'
import { SafeAreaProvider } from 'react-native-safe-area-context'
import { Provider as ReduxProvider } from 'react-redux'
import renderer, { ReactTestInstance } from 'react-test-renderer'
import createMockStore from 'redux-mock-store'
import { ThemeProvider } from 'styled-components/native'
import { TRootState } from '@app/core/state/root'
import { initialState } from '@app/core/state/mockedInitialState'
import { theme } from '@app/themes'
type DeepPartial<T> = {
[P in keyof T]?: DeepPartial<T[P]>
}
type TConfig = {
mockRedux?: boolean
mockSafeAreaProvider?: boolean
mockTheme?: boolean
state?: DeepPartial<TRootState>
}
const initialMetrics = {
frame: { height: 0, width: 0, x: 0, y: 0 },
insets: { bottom: 0, left: 0, right: 0, top: 0 },
}
export function createMockedElement(element: React.ReactElement, config?: TConfig) {
let mockedElement = element
if (config?.mockRedux !== false) {
const middlewares = getDefaultMiddleware()
const mockStore = createMockStore(middlewares)
const state = lodash.merge(initialState, config?.state)
const store = mockStore(state)
mockedElement = <ReduxProvider store={store}>{mockedElement}</ReduxProvider>
}
if (config?.mockTheme !== false) {
mockedElement = <ThemeProvider theme={theme}>{mockedElement}</ThemeProvider>
}
if (config?.mockSafeAreaProvider !== false) {
mockedElement = <SafeAreaProvider initialMetrics={initialMetrics}>{mockedElement}</SafeAreaProvider>
}
return mockedElement
}
export function createReactTestInstance(element: React.ReactElement, config?: TConfig): ReactTestInstance {
return renderer.create(createMockedElement(element, config)).root
}
여기에서 진행 중인 일이 매우 많으니 분해해 보겠습니다. 하지만 먼저 이야기해야 할 것은...
도우미 함수가 실제로 어떻게 사용되는지
저는 항상 이러한 도우미 메서드를 야생에서 사용하는 방법을 먼저 이해하는 것이 더 쉽다고 생각합니다. 따라서 이러한 도우미를 테스트에 통합하는 방법에 대한 예를 추가했습니다. 이것은 예상 요소의 존재 여부를 확인하는 데 유용한 React’s Test Renderer을 사용합니다.
import { createReactTestInstance } from './testHelpers'
describe('MyComponent tests', () => {
it('renders correct version for users who shown interest', () => {
const instance = createReactTestInstance(<MyComponent />)
expect(instance.findByProps({ testID: `interested-icon` })).toBeTruthy()
})
it('renders correct version for users who have not shown interest', () => {
const instance = createReactTestInstance(<MyComponent />)
expect(instance.findByProps({ testID: `not-interested-icon` })).toBeTruthy()
})
})
특정 사용자 작업이 특정 기대치를 초래하는지 여부를 테스트하려는 경우 React Testing Library(React의 테스트 렌더러 위에 위치)가 적합합니다.
createReactTestInstance
도우미를 사용하는 대신 createMockedElement
도우미를 사용할 수 있습니다. 다음은 예입니다.import { fireEvent, render } from '@testing-library/react-native'
import { act } from 'react-test-renderer'
import { createMockedElement } from './testHelpers'
const navigateMock = jest
.mock
// your mock...
()
describe('BackButton tests', () => {
it('navigates to the right screen onPress', async () => {
const mockedElement = createMockedElement(<BackButton previousScreen="PreviousScreenName" />)
const renderAPI = await render(mockedElement)
await act(async () => {
const backButton = renderAPI.getByTestId('button-back-navigation')
await fireEvent.press(backButton)
expect(navigateMock).toHaveBeenCalledWith('PreviousScreenName')
})
})
})
이제 도우미 함수가 실제로 어떻게 사용되는지 이해했으므로 도우미 파일을 설정하는 방법으로 돌아가 보겠습니다.
도우미 파일 방식 깨기
이 파일의 핵심은
createMockedElement
함수입니다.export function createMockedElement(element: React.ReactElement, config?: TConfig) {
let mockedElement = element
if (config?.mockRedux !== false) {
const middlewares = getDefaultMiddleware()
const mockStore = createMockStore(middlewares)
const state = lodash.merge(initialState, config?.state)
const store = mockStore(state)
mockedElement = <ReduxProvider store={store}>{mockedElement}</ReduxProvider>
}
if (config?.mockTheme !== false) {
mockedElement = <ThemeProvider theme={theme}>{mockedElement}</ThemeProvider>
}
if (config?.mockSafeAreaProvider !== false) {
mockedElement = <SafeAreaProvider initialMetrics={initialMetrics}>{mockedElement}</SafeAreaProvider>
}
return mockedElement
}
이 함수는 테스트하려는 요소/구성 요소와 선택적
config
개체의 두 가지 인수를 사용합니다. 이 구성 개체를 사용하면 테스트 중에 구성 요소를 렌더링할 때 포함할 래퍼(있는 경우)를 지정할 수 있습니다. 예를 들어 Redux 상태를 조롱해야 하는 경우 다음과 같이 테스트를 설정할 수 있습니다.it("doesn't open the modal when row is active", async () => {
const mockedState = { show_modal: false }
const config = { state: mockedState }
const mockedElement = createMockedElement(<Row />, config)
const renderAPI = await render(mockedElement)
await act(async () => {
// ... your test expectations
})
})
ThemeProvider
및/또는 SafeAreaProvider
래퍼를 포함해야 하는 경우에도 마찬가지로 동일하게 수행할 수 있습니다. TConfig
에 정의된 대로 이 두 옵션은 boolean
입력을 받습니다.Redux 상태 설정에 대해 자세히 알아보기
Redux 상태를 조롱할 때 테스트 Redux 상태가 일부 초기 값으로 설정되었는지 확인해야 합니다. 이를 위해 다양한 Redux Toolkit 슬라이스에서 모든 초기 상태를 추출하고 단일 객체로 결합한 다음
lodash
병합 기능에 전달했습니다(모의 상태와 완전히 병합되도록).// @app/core/state/mockedInitialState
import { initialStateFeature1 } from '@covid/core/state/feature1.slice'
import { initialStateFeature2 } from '@covid/core/state/feature2.slice'
import { initialStateFeature3 } from '@covid/core/state/feature3.slice'
export const initialState: TRootState = {
feature1: initialStateFeature1,
feature2: initialStateFeature2,
feature3: initialStateFeature3,
}
그리고 그게 다야! 이것이 React Native 테스트 생활을 조금 더 쉽게 만들어주기를 바랍니다. 😄 저를 위한 제안이나 개선 사항이 있으면 알려주세요. 저는 항상 테스트 게임을 즐기고 있습니다! 나는 https://bionicjulia.com에 있고 .
Reference
이 문제에 관하여(고차 컴포넌트로 React Native Jest 테스트 설정하기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/bionicjulia/setting-up-react-native-jest-tests-with-higher-order-components-mn4텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)