我想测试一个使用全局fetch
方法的小型 React Web 应用程序。
我试图以fetch
这种方式嘲笑:
global.fetch = jest.spyOn(global, 'fetch').mockImplementation(endpoint =>
Promise.resolve({
json: () => Promise.resolve(mockResponse)
})
);
...但模拟似乎被忽略,而内置fetch
似乎被使用:Error: connect ECONNREFUSED 127.0.0.1:80 ...
看起来像是对内置的调用失败fetch
。
然后我尝试使用jest.fn
而不是jest.spyOn
:
global.fetch = jest.fn(endpoint =>
Promise.resolve({
json: () => Promise.resolve(mockResponse)
})
);
...并惊讶地看到一个不同的错误。现在模拟似乎被考虑在内,但同时无法正常工作:
TypeError: Cannot read property 'then' of undefined
8 | this.updateTypes = this.props.updateTypes;
9 | this.updateTimeline = this.props.updateTimeline;
> 10 | fetch('/timeline/tags')
| ^
11 | .then(res => res.json())
12 | .then(tags => tags.map(tag => <option value={tag} key={tag} />))
13 | .then(options => options.sort((a, b) => a.key.localeCompare(b.key)))
老实说,我发现 Jest 和 React 测试库的文档有点混乱。我正在做的事情可能有什么问题?
编辑
我尝试测试的 React 组件称为“App”,是使用 Create React App 生成的,并更改为包括对fetch
. 我很乐意提供这个组件的代码,但我相信问题出在测试上。
在我的App.test.js
文件的开头, I import React from 'react';
,然后是import { render, fireEvent, waitFor, screen } from '@testing-library/react';
,最后是import App from './App';
。我随后尝试以fetch
我描述的方式之一进行模拟,然后声明以下测试:
test('renders a list of items, upon request', async () => {
const app = render(<App />);
fireEvent.click(screen.getByText('Update'));
await waitFor(() => screen.getByRole('list'));
expect(screen.getByRole('list')).toBeInTheDocument();
expect(screen.getByRole('list')).toHaveClass('Timeline');
});
最后,我以global.fetch.mockRestore();
.