我想测试一个小的React Web应用,其中使用全局fetch
方法。
我尝试通过以下方式模拟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 Testing Library 的文档有点令人困惑,说实话。我所做的可能存在问题是什么?
编辑
我正在尝试测试的 React 组件名为“App”,使用 Create React App 生成,并更改以包含对 fetch
的调用。我可以很高兴地提供此组件的代码,但我认为问题在于测试。
在我的 App.test.js
文件开头,我首先 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();
结束了我的测试文件。
fetch
,并且在缺少属性的情况下调用jest.spyOn是不允许的。我看不到第二个模拟单独出现无法读取未定义的“then”属性错误的可能性,除非错误指的是另一行,如果源映射出错,则可能发生这种情况。 - Estus FlaskApp
组件的代码),请让我知道,我会编辑我的问题。 - Giorgio