我是一个测试react-native项目的新手,但通常我理解mocking的概念。在一个新的测试中,由于“全局”应用程序提供商的原因,需要进行大量的设置,其中一个设置在我的测试中抛出了一个错误:
TypeError: Cannot read properties of undefined (reading 'settings')
字符串
堆栈跟踪转到:
onst deviceLocale: Locales =
Platform.OS === 'ios'
? NativeModules.SettingsManager.settings.AppleLocale ||
NativeModules.SettingsManager.settings.AppleLanguages[0]
: NativeModules.I18nManager.localeIdentifier;
型
这意味着在NativeModules导入中没有SettingsManager
:import { NativeModules, Platform } from 'react-native';
个
我已经尝试了很多方法来模拟react-native
,但这也有它自己的问题。我不想让SettingsManager
成为可选链接,因为没有理由这样做。
我是否应该更改我的配置/设置文件?这是一个受管理的世博会工作流程。
Jest配置:
module.exports = {
preset: 'jest-expo',
setupFilesAfterEnv: [
'<rootDir>/src/test-utils/jest-setup.ts',
'@testing-library/jest-native/extend-expect',
],
collectCoverage: false,
transform: {
'^.+\\.(js|jsx|ts|tsx)$': 'babel-jest',
},
transformIgnorePatterns: [
'node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg|@rneui/.*|@fluidtruck/.*|@expo/.*)',
],
};
型
会不会是我的transformIgnorePatterns
?
我的jest.setup
文件是:
import 'cross-fetch/polyfill';
import '@testing-library/jest-native/extend-expect';
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import { NativeModules } from 'react-native';
import { en } from '@/locales/en';
import { es } from '@/locales/es';
import { server } from '../mocks/server';
const resources = {
en,
es,
};
beforeAll(() => {
server.listen();
jest.mock('react-i18next', () => ({
useTranslation: () => {
return {
t: (str: string) => str,
i18n: {
changeLanguage: () => new Promise(jest.fn),
},
};
},
}));
i18n.use(initReactI18next).init({
lng: 'en',
defaultNS: 'common',
debug: false,
resources,
});
jest.mock('@react-navigation/core', () => {
const actualNav = jest.requireActual('@react-navigation/core');
return {
...actualNav,
useNavigation: () => ({
navigate: jest.fn(),
dispatch: jest.fn(),
goBack: jest.fn(),
}),
useRoute: () => ({
params: jest.fn(),
}),
};
});
});
jest.mock('@react-navigation/native');
jest.mock('@react-native-async-storage/async-storage', () =>
require('@react-native-async-storage/async-storage/jest/async-storage-mock')
);
afterEach(() => server.resetHandlers());
afterAll(() => server.close());
型
我试着加了这个模拟,
jest.mock('react-native', () => {
const actual = jest.requireActual('react-native');
return {
...actual,
NativeModules: jest.fn(),
};
});
型
但它导致了太多的警告沿着这条线:
PushNotificationIOS已从react-native核心中提取,并将在未来版本中删除。它现在可以从'@react-native-community/push-notification-ios'而不是'react-native'安装和导入。参见https://github.com/react-native-push-notification-ios/push-notification-ios
而我的实际测试文件,我试图在提供者钩子中测试一个方法,我甚至还没有能够做到这一点:
import { act, renderHook } from '@testing-library/react-hooks';
import React, { ReactNode } from 'react';
import { Wrapper } from '@/src/test-utils/wrapper';
import { VehicleDataProvider } from '../../../Vehicle';
import { InspectionData } from '../../InspectionsDataProvider/__fixtures__/inspection.fixture';
import { InspectionsDataProvider } from '../../InspectionsDataProvider/InspectionsDataProvider';
import { ActiveInspectionProvider } from '../ActiveInspectionProvider';
import { useActiveInspectionContext } from '../useActiveInspectionContext';
describe('useActiveInspectionProvider', () => {
test('#handleNextPress sends expected payload', async () => {
jest.mock('@react-navigation/native', () => ({
...jest.requireActual('@react-navigation/native'),
useRoute: () => ({
params: {
aggId: '',
section: '0eafdffc-8ba5-45b6-ada8-9372dabe81c2',
step: '1e46bdf9-a30a-4d41-bc61-a39b0a86d2f3',
name: 'Dev 1',
vehicleId: '26284',
},
}),
}));
const wrapper = ({ children }: { children: ReactNode }) => {
console.log({ children });
return (
<Wrapper>
<VehicleDataProvider>
<InspectionsDataProvider>
<ActiveInspectionProvider>{children}</ActiveInspectionProvider>
</InspectionsDataProvider>
</VehicleDataProvider>
</Wrapper>
);
};
const { result, waitForNextUpdate } = renderHook(() => useActiveInspectionContext(), {
wrapper,
});
act(() => {
if (!InspectionData.formGroups[1].formFields[0].formFieldOptions) {
throw new Error('Missing FormField options data');
}
console.log(result.current);
result.current.handleNextPress({
[InspectionData.formGroups[1].formFields[0].uuid]:
InspectionData.formGroups[1].formFields[0].formFieldOptions[1].value,
});
});
await waitForNextUpdate();
expect(fetch as jest.Mock).toHaveBeenLastCalledWith();
});
});
型
我使用的版本:“jest”:“^27.4.7”,“jest-expo”:“^44.0.1”,“react-native”:“0.69.6”,“expo”:“~46.0.19”,
我可以用jest对NativeModules
做什么?
1条答案
按热度按时间f45qwnt81#
你需要在React-native中模拟Native模块。试试这个:
字符串