我面临一个问题,在我将 Select UI 组件从gluestack-ui 添加到我的 React Native 组件后,我的测试无法通过文本找到元素。
在添加选择之前,我的测试工作正常:
测试-utils.tsx
import React from 'react'
import {render} from '@testing-library/react-native'
import { GluestackUIProvider } from "@/components/ui/gluestack-ui-provider";
import fs from 'fs';
const AllTheProviders = ({children}) => {
return (
<GluestackUIProvider>
{children}
</GluestackUIProvider>
)
}
const customRender = (ui, options?) => {
const view = render(ui, {wrapper: AllTheProviders, ...options})
const style = document.createElement('style');
style.innerHTML = fs.readFileSync('./output.css', 'utf8');
document.head.appendChild(style);
return view;
}
// re-export everything
export * from '@testing-library/react-native'
// override render method
export {customRender as render}
我的组件
import React, { useState } from 'react';
import { View, FlatList } from 'react-native';
import { Text } from '@/components/ui/text';
import { Input, InputField } from '@/components/ui/input';
import { Heading } from '../ui/heading';
export const JamSessionsBanner = ({ sessions }) => {
const [lieu, setLieu] = useState('');
const [date, setDate] = useState('');
const filteredSessions = sessions.filter((session) => {
const matchesLieu = lieu ? session.lieu.toLowerCase().includes(lieu.toLowerCase()) : true;
const matchesDate = date ? new Date(session.date).toDateString() === new Date(date).toDateString() : true;
return matchesLieu && matchesDate;
});
return (
<View style={{ padding: 16 }}>
<Heading>Upcoming JAM Sessions</Heading>
<FlatList
data={filteredSessions}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<View style={{ marginBottom: 16 }}>
<Text>{item.lieu}, {item.ville}</Text>
<Text>{new Date(item.date).toLocaleString()}</Text>
</View>
)}
/>
</View>
);
};
数据
export const mockSessions = [
{
id: '1',
date: '2024-10-18T19:30:00',
lieu: 'Le Café',
ville: 'Paris',
description: 'Session de jam ouverte à tous.',
musiciens: ['John Doe', 'Jane Smith'],
popularité: 100,
genre: 'reggae',
},
{
id: '2',
date: '2024-10-20T20:00:00',
lieu: 'La Ska Factory',
ville: 'Lyon',
description: 'Jam session ska.',
musiciens: ['Paul Dupont', 'Marie Lafont'],
popularité: 80,
genre: 'ska',
},
];
笑话配置
module.exports = {
preset: 'react-native',
transform: {
'^.+\\.tsx?$': 'babel-jest',
},
setupFilesAfterEnv: ['<rootDir>/setupTests.ts'],
moduleNameMapper: {
'\\.(jpg|jpeg|png|gif|svg)$': 'jest-transform-stub',
'\\.(css|less|scss|sass)$': 'identity-obj-proxy',
},
testEnvironment: 'jsdom',
testPathIgnorePatterns: [
'<rootDir>/node_modules/',
'<rootDir>/e2e/',
"node_modules/(?!((jest-)?react-native|@react-native(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|@gluestack-ui/*|@gluestack-style/*|@legendapp/*|react-native-svg)",
],
};
测试(通过):
import { render, screen } from '../../test-utils';
import { JamSessionsBanner } from './JamSessionsBanner';
import { mockSessions } from './jam.mock';
test('renders sessions correctly', () => {
render(<JamSessionsBanner sessions={mockSessions} />);
expect(screen.getByText(/Le Café, Paris/i)).toBeTruthy();
});
添加Select组件后,测试失败:
import React, { useState } from 'react';
import { View, FlatList } from 'react-native';
import { Text } from '@/components/ui/text';
import { Input, InputField } from '@/components/ui/input';
import { Heading } from '../ui/heading';
import {
Select,
SelectBackdrop,
SelectContent,
SelectIcon,
SelectInput,
SelectItem,
SelectPortal,
SelectTrigger
} from '@/components/ui/select';
import { ChevronDownIcon } from '../ui/icon';
export const JamSessionsBanner = ({ sessions }) => {
const [lieu, setLieu] = useState('');
const [date, setDate] = useState('');
const [selectedVille, setSelectedVille] = useState('Partout');
const villes = ['Partout', ...new Set(sessions.map(session => session.ville))];
const filteredSessions = sessions.filter((session) => {
const matchesLieu = lieu ? session.lieu.toLowerCase().includes(lieu.toLowerCase()) : true;
const matchesDate = date ? new Date(session.date).toDateString() === new Date(date).toDateString() : true;
return matchesLieu && matchesDate;
});
return (
<View style={{ padding: 16 }}>
<Heading>
Upcoming JAM Sessions
<Select selectedValue={selectedVille} onValueChange={setSelectedVille}>
<SelectTrigger variant="outline">
<SelectInput placeholder="Filter by city" />
<SelectIcon as={ChevronDownIcon} />
</SelectTrigger>
<SelectPortal>
<SelectBackdrop />
<SelectContent>
{villes.map(ville => (
<SelectItem key={ville} label={ville} value={ville} />
))}
</SelectContent>
</SelectPortal>
</Select>
</Heading>
<FlatList
data={filteredSessions}
keyExtractor={(item) => item.id}
renderItem={({ item }) => (
<View style={{ marginBottom: 16 }}>
<Text>{item.lieu}, {item.ville}</Text>
<Text>{new Date(item.date).toLocaleString()}</Text>
</View>
)}
/>
</View>
);
};
测试现在失败并出现以下错误:
Unable to find an element with text: /Le Café, Paris/i
完整的控制台输出:
FAIL components/JamSessionsBanner/JamSessionsBanner.test.tsx (5.291 s)
JamSessionsBanner
✕ renders sessions correctly (726 ms)
● JamSessionsBanner › renders sessions correctly
Unable to find an element with text: /Le Café, Paris/i
<View>
<View>
<RCTText
accessibilityRole="header"
accessible={true}
>
Upcoming JAM Sessions
<View>
<View
accessible={true}
role="button"
>
<TextInput
aria-hidden={true}
importantForAccessibility="no"
placeholder="Filter by city"
value="Partout"
/>
<RNSVGSvgView
role="img"
>
<RNSVGGroup>
<RNSVGGroup>
<RNSVGPath />
</RNSVGGroup>
</RNSVGGroup>
</RNSVGSvgView>
</View>
</View>
</RCTText>
<RCTScrollView>
<RCTScrollContentView>
<View>
<View>
<RCTText
accessible={true}
>
Le Café
,
Paris
</RCTText>
<RCTText
accessible={true}
>
18/10/2024 19:30:00
</RCTText>
</View>
</View>
<View>
<View>
<RCTText
accessible={true}
>
La Ska Factory
,
Lyon
</RCTText>
<RCTText
accessible={true}
>
20/10/2024 20:00:00
</RCTText>
</View>
</View>
</RCTScrollContentView>
</RCTScrollView>
</View>
</View>
10 | render(<JamSessionsBanner sessions={mockSessions} />);
11 | // expect(screen.getByText(/Session de jam ouverte à tous/i)).toBeTruthy();
> 12 | expect(screen.getByText(/Le Café, Paris/i)).toBeTruthy();
| ^
13 | });
14 |
15 | // test('displays empty state when no sessions are available', async () => {
at Object.getByText (components/JamSessionsBanner/JamSessionsBanner.test.tsx:12:19)
at asyncGeneratorStep (node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:17)
at asyncGeneratorStep (node_modules/@babel/runtime/helpers/asyncToGenerator.js:17:9)
at _next (node_modules/@babel/runtime/helpers/asyncToGenerator.js:22:7)
at Object.<anonymous> (node_modules/@babel/runtime/helpers/asyncToGenerator.js:14:12)
Test Suites: 1 failed, 1 total
Tests: 1 failed, 1 total
Snapshots: 0 total
Time: 6.34 s
我尝试过的:
有谁知道为什么@testing-library/react-native添加Select后可能找不到文本?
如果您对添加 Select 可能导致此问题的原因有任何见解,或者如果我在测试设置中遗漏了某些内容,我将不胜感激!
@loann-delgado 此问题有任何更新吗?我也遇到同样的问题了