【发布时间】:2021-09-11 01:30:39
【问题描述】:
我有一个简单的 React 组件,它调用本地 API 来获取组件挂载上的产品列表。功能本身运行良好。该应用程序由 create-react-app 创建。 但是,我也在尝试在 Jest 中测试 fetch 函数,但我的模拟全局 fetch 总是返回 null。有谁知道为什么?
这就像我的模拟函数甚至从未被调用或者不在组件逻辑的范围内?然而,原始的全局提取也不会被调用。只返回 null。
我还尝试重写我的 fetch 以使用 .then() 后续操作,并且我尝试使用 jest-fetch-mock 包,但结果是相同的。我可以从测试中调用我的(真实)获取函数,它会正确返回。只有模拟的 fetch 会导致问题。
这是我一直在关注的教程: https://www.leighhalliday.com/mock-fetch-jest
组件:
import React, { useState, useEffect } from 'react';
import Product from './Product';
import './Shop.css';
export async function fetchProducts() {
try {
const result = await fetch('http://localhost:8080/products', {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
});
const data = await result.json();
return data;
} catch (e) {
return null;
}
}
function Shop() {
const [products, setProducts] = useState([])
useEffect(async () => {
const result = await fetchProducts();
setProducts(result);
}, []);
return (
<>
<h2>Shop</h2>
<ul className='list-reset products-wrapper'>
{products.map((product) => (
<Product
key={product.id}
{...product} />
))}
</ul>
</>
);
}
export default Shop;
测试:
import { render, screen } from '@testing-library/react';
import Shop, { fetchProducts } from './Shop';
// Mocking the fetch function
global.fetch = jest.fn(() => {
return Promise.resolve({
json: () => Promise.resolve([
{
id: '1',
productName: 'Banana',
price: 0.39,
image: '????'
}
])
})
});
beforeEach(() => {
fetch.mockClear();
});
test('requests the products on mount', async () => {
const products = await fetchProducts();
expect(products).toEqual({
id: '1',
productName: 'Banana',
price: 0.39,
image: '????'
})
});
测试失败:
FAIL src/components/Shop/Shop.test.js
● requests the products on mount
expect(received).toEqual(expected) // deep equality
Expected: {"id": "1", "image": "????", "price": 0.39, "productName": "Banana"}
Received: null
如果我在测试运行时注销模拟的 fetch 方法,它会记录 Jest 模拟:
[Function: mockConstructor] {
_isMockFunction: true,
getMockImplementation: [Function],
mock: [Getter/Setter],
mockClear: [Function],
mockReset: [Function],
mockRestore: [Function],
mockReturnValueOnce: [Function],
mockResolvedValueOnce: [Function],
mockRejectedValueOnce: [Function],
mockReturnValue: [Function],
mockResolvedValue: [Function],
mockRejectedValue: [Function],
mockImplementationOnce: [Function],
mockImplementation: [Function],
mockReturnThis: [Function],
mockName: [Function],
getMockName: [Function]
}
【问题讨论】:
-
我已经通过使用
global.fetch = jest.fn().mockReturnValue(Promise.resolve({//stuff}))得到了这个工作,虽然我不完全确定有什么区别 -
是 ///stuff 返回的对象吗?它也返回 null
-
//stuff在这种情况下将是json: () => Promise.resolve([//return values]}基本上只需将jest.fn(()=>)更改为jest.fn().mockReturnValue() -
global.fetch = jest.fn().mockReturnValue(Promise.resolve({ json: () => Promise.resolve([ { id: '1', productName: 'Banana', price: 0.39, image: '????' } ]) }))也返回 null 但感谢您的建议 -
那么在这种情况下,我会尝试更改您的 catch 语句以记录一条消息并查看它捕获的错误是什么
标签: javascript reactjs testing jestjs mocking