如何测试依赖于要呈现的布尔变量的标签?例如,如果变量isLoading
为true,则它将呈现<p>Loading...</p>
。
我试着去测试,却得到一个错误:
// AutoComplete.test.tsx
import React from 'react';
import { render, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import AutoComplete from './AutoComplete';
describe('AutoComplete component', () => {
test('renders loading state when isLoading is true', () => {
render(<AutoComplete />);
const loadingElement = screen.getByText('Loading...');
expect(loadingElement).toBeInTheDocument();
});
test('renders "No countries found" when inputValue is at least 3 characters and searchResults is empty', () => {
render(<AutoComplete />);
const inputElement = screen.getByPlaceholderText('Search Country...');
userEvent.type(inputElement, 'abc');
const noCountriesElement = screen.getByText('No countries found');
expect(noCountriesElement).toBeInTheDocument();
});
});
// AutoComplete.tsx
import React, { useContext, useState, useEffect, useCallback } from 'react';
import { DataContext } from 'src/contexts';
import { Country } from 'src/types';
import Input from '../Input';
import './index.css';
const AutoComplete = () => {
const { inputValue } = useContext(DataContext);
const [searchResults, setSearchResults] = useState<Country[]>([]);
const [isLoading, setIsLoading] = useState(false);
const fetchData = async (value: string) => {
setIsLoading(true);
try {
const response = await fetch(
`https://restcountries.com/v3/name/${value}`
);
if (response.ok) {
const data = await response.json();
setSearchResults(data);
} else {
setSearchResults([]);
}
} catch (error) {
console.error('Error fetching data:', error);
}
setIsLoading(false);
};
const filterResults = useCallback(
(results: Country[]) => {
return results.filter((country) =>
country.name.common.toLowerCase().includes(inputValue)
);
},
[inputValue]
);
const highlightSearchTerm = (text: string) => {
const regex = new RegExp(`(${inputValue})`, 'gi');
return text.replace(regex, '<span class="highlight">$1</span>');
};
useEffect(() => {
if (inputValue && inputValue.length >= 3) {
fetchData(inputValue);
} else {
setSearchResults([]);
}
}, [inputValue]);
return (
<div>
<h1>Auto Complete</h1>
<Input />
<h2>Results: </h2>
{isLoading ? (
<p>Loading...</p>
) : inputValue?.length >= 3 && searchResults.length === 0 ? (
<p>No countries found</p>
) : (
<ul>
{filterResults(searchResults).map((country, index) => (
<li key={index}>
<h3
dangerouslySetInnerHTML={{
__html: highlightSearchTerm(country.name.common),
}}
/>
</li>
))}
</ul>
)}
</div>
);
};
export default AutoComplete;
1条答案
按热度按时间aurhwmvo1#
如果你想让
Loading...
文本出现在屏幕上,你必须触发fetchData
函数,这是一个设置isLoading
到true
。您可以通过模拟用户输入并保证fetch
函数不返回任何数据来做到这一点。我没有测试过这段代码,我不知道
testing-library
是否会在文本出现在屏幕上时捕获它,但你可能必须使用mock fetch,原因有二:Loading...
有机会出现在屏幕上。