【发布时间】:2020-05-10 12:48:49
【问题描述】:
我想测试应该显示在我的功能组件中的 api 调用和返回的数据。我创建了执行 api 调用的 List 组件。我希望返回的数据显示在组件中,为此我使用了 useState 挂钩。组件如下所示:
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 id="test">{data}</div>
</div>
)
}
我写了一个测试来模拟 fetch 方法。我检查是否调用了 fetch 方法并且它确实发生了。不幸的是,我不知道如何测试从响应返回的值。当我尝试 console.log 时,我只是得到 null 并且我想得到“示例文本”。我的猜测是我必须等待从 Promise 返回的这个值。不幸的是,尽管尝试了方法行为和等待,但我不知道如何实现它。这是我的测试:
it('test', async () => {
let component;
const fakeResponse = 'example text';
const mockFetch = Promise.resolve({json: () => Promise.resolve(fakeResponse)});
const mockedFetch = jest.spyOn(window, 'fetch').mockImplementationOnce(() => mockFetch as any )
await wait( async () => {
component = render(<List />);
})
const value: 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>
)
}
和更新的测试:
it('test', async () => {
const fakeResponse = 'example text';
const mockFetch = Promise.resolve({json: () => Promise.resolve(fakeResponse)});
const mockedFetch = jest.spyOn(window, 'fetch').mockImplementationOnce(() => mockFetch as any )
const { getByTestId } = render(<List />);
expect(getByTestId("test")).toHaveTextContent("test");
const resolvedValue = await waitForElement(() => getByTestId('test'));
expect(resolvedValue).toHaveTextContent("example text");
expect(mockedFetch).toHaveBeenCalledTimes(1);
})
【问题讨论】:
-
好的,在我的代码和测试中一切都很好。只是我在模拟数据中犯了一个错误。在我的组件中,我试图访问标题键。在测试中,我嘲笑了一个愚蠢的字符串,这就是我收到空值的原因。
-
在谷歌搜索中找到了这个——我建议用最终版本更新你的问题。看起来您的帖子有几个不同的变体
-
偶然发现这个,同样有兴趣知道这个断言是否通过了 `expect(mockedFetch).toHaveBeenCalledTimes(1); `
标签: reactjs typescript unit-testing react-hooks react-testing-library