从gluestack-ui v.2 添加 Select 组件后出现 @testing-library 问题

问题描述 投票:0回答:1

我面临一个问题,在我将 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 配置正确,并且自定义渲染包含必要的上下文提供程序。
  • 我尝试在测试中添加 waitFor 。
  • 该问题似乎仅在添加 Select 组件后才出现。没有它,一切都会按预期进行。
  • 我已经检查了应用程序中的选择渲染和功能,并且在手动测试时它可以正常工作。

有谁知道为什么@testing-library/react-native添加Select后可能找不到文本?

如果您对添加 Select 可能导致此问题的原因有任何见解,或者如果我在测试设置中遗漏了某些内容,我将不胜感激!

react-native react-native-testing-library gluestack
1个回答
0
投票

@loann-delgado 此问题有任何更新吗?我也遇到同样的问题了

© www.soinside.com 2019 - 2024. All rights reserved.