Reactjs 使用react测试库测试useEffect内部的api调用
我想测试api调用和返回的数据,这些数据应该显示在我的功能组件中。我创建了执行api调用的列表组件。我希望返回的数据显示在组件中,我使用useState钩子来实现这一点。组件如下所示:Reactjs 使用react测试库测试useEffect内部的api调用,reactjs,typescript,unit-testing,react-hooks,react-testing-library,Reactjs,Typescript,Unit Testing,React Hooks,React Testing Library,我想测试api调用和返回的数据,这些数据应该显示在我的功能组件中。我创建了执行api调用的列表组件。我希望返回的数据显示在组件中,我使用useState钩子来实现这一点。组件如下所示: const列表:FC=()=>{ const[data,setData]=useState(); const getData=():Promise=>{ 返回获取('https://jsonplaceholder.typicode.com/todos/1'); }; React.useffect(()=>{ co
const列表:FC=()=>{
const[data,setData]=useState();
const getData=():Promise=>{
返回获取('https://jsonplaceholder.typicode.com/todos/1');
};
React.useffect(()=>{
const func=async()=>{
const data=wait getData();
const value=wait data.json();
setData(value.title);
}
func();
}, [])
返回(
{data}
)
}
我编写了一个测试,其中模拟了fetch方法。我检查fetch方法是否被调用,它是否真的发生了。不幸的是,我不知道如何测试从响应返回的值。当我尝试console.log时,我只得到null,我想得到“示例文本”。我的猜测是,我必须等待Promise返回的值。不幸的是,尽管尝试了一些方法,但我不知道如何实现它。这是我的测试:
it('test',async()=>{
let组件;
const fakeResponse='示例文本';
const mockFetch=Promise.resolve({json:()=>Promise.resolve(fakeResponse)});
const mockedFetch=jest.spyOn(窗口“fetch”).mockImplementationOnce(()=>mockFetch as any)
等待等待(异步()=>{
组件=渲染();
})
常量值:Element=component.container.querySelector(“#test”);
console.log(value.textContent);
expect(mockedFetch).toHaveBeenCalledTimes(1);
})
如果有任何建议,我将非常感激
第二次尝试
还尝试使用data testid=“test”
和waitForElement
,但仍接收空值
更新的组件增量:
const List: FC<{}> = () => {
- const [data, setData] = useState<number>();
+ const [data, setData] = useState<string>('test');
const getData = (): Promise<any> => {
return fetch('https://jsonplaceholder.typicode.com/todos/1');
};
React.useEffect(() => {
const func = async () => {
const data = await getData();
const value = await data.json();
setData(value.title);
}
func();
}, [])
return (
<div>
- <div id="test">{data}</div>
+ <div data-testid="test" id="test">{data}</div>
</div>
)
}
const列表:FC=()=>{
-const[data,setData]=useState();
+const[data,setData]=useState('test');
const getData=():Promise=>{
返回获取('https://jsonplaceholder.typicode.com/todos/1');
};
React.useffect(()=>{
const func=async()=>{
const data=wait getData();
const value=wait data.json();
setData(value.title);
}
func();
}, [])
返回(
-{data}
+{data}
)
}
和更新的测试:
it('test',async()=>{
const fakeResponse='示例文本';
const mockFetch=Promise.resolve({json:()=>Promise.resolve(fakeResponse)});
const mockedFetch=jest.spyOn(窗口“fetch”).mockImplementationOnce(()=>mockFetch as any)
const{getByTestId}=render();
期望(getByTestId(“测试”))。拥有文本内容(“测试”);
const resolvedValue=wait waitForElement(()=>getByTestId('test');
expect(resolvedValue).toHaveTextContent(“示例文本”);
expect(mockedFetch).toHaveBeenCalledTimes(1);
})
以下是一个工作单元测试示例:
index.tsx
:
import React, { useState, FC } from 'react';
export const List: FC<{}> = () => {
const [data, setData] = useState<number>();
const getData = (): Promise<any> => {
return fetch('https://jsonplaceholder.typicode.com/todos/1');
};
React.useEffect(() => {
const func = async () => {
const data = await getData();
const value = await data.json();
setData(value.title);
};
func();
}, []);
return (
<div>
<div data-testid="test">{data}</div>
</div>
);
};
import { List } from './';
import React from 'react';
import '@testing-library/jest-dom/extend-expect';
import { render, waitForElement } from '@testing-library/react';
describe('59892259', () => {
let originFetch;
beforeEach(() => {
originFetch = (global as any).fetch;
});
afterEach(() => {
(global as any).fetch = originFetch;
});
it('should pass', async () => {
const fakeResponse = { title: 'example text' };
const mRes = { json: jest.fn().mockResolvedValueOnce(fakeResponse) };
const mockedFetch = jest.fn().mockResolvedValueOnce(mRes as any);
(global as any).fetch = mockedFetch;
const { getByTestId } = render(<List></List>);
const div = await waitForElement(() => getByTestId('test'));
expect(div).toHaveTextContent('example text');
expect(mockedFetch).toBeCalledTimes(1);
expect(mRes.json).toBeCalledTimes(1);
});
});
单元测试结果:
PASS src/stackoverflow/59892259/index.test.tsx (9.816s)
59892259
✓ should pass (63ms)
-----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
-----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
index.tsx | 100 | 100 | 100 | 100 | |
-----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 11.73s, estimated 13s
好的,我的代码和测试都很好。我只是在模拟数据中犯了一个错误。在我的组件中,我试图访问标题键。在测试中,我模仿了一个愚蠢的字符串,这就是为什么我收到空值。在谷歌搜索中发现了这个——我建议用最终版本更新你的问题。看起来你的帖子有几个不同的变量,同样有兴趣知道这个断言是否通过了'expect(mockedFetch).toHaveBeenCalledTimes(1)`