我正在开发一个 React 项目,其中有一个使用可选链和 try-catch 块来分配导航函数的函数。我正在尝试编写一个 Jest 测试来覆盖 catch 块,但我很难触发它。代码如下:
import { useNavigate } from 'react-router-dom';
let navigate;
function useNavigateMFE() {
try {
// Assign the navigate function based on the availability of the hfe properties.
navigate = window?.hfe?.testdevice
? window?.hfe?.histr
: useNavigate(); // Fallback to the standard useNavigate function if conditions are not met.
} catch (e) {
console.log("An error occurred:", e);
// Optionally, provide a fallback action or handling in case of an error.
}
}
// Call the function to set the navigate variable.
useNavigateMFE();
注意:每当组件渲染时都会触发
我尝试过的 我尝试了以下方法来覆盖 catch 块:
模拟 window.hfe 为 null 或未定义:这不会触发 catch 块,可能是因为可选链接可以防止抛出错误。 模拟useNavigate函数抛出错误:
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useNavigate: () => {
throw new Error("Mocked error");
},
}));
尽管如此,测试中仍然没有涵盖 catch 块。
我的目标 我想模拟一个触发 useNavigateMFE 函数中的 catch 块的错误。这是我当前测试用例的示例:
import { useNavigate } from 'react-router-dom';
jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useNavigate: jest.fn(() => {
throw new Error("Mocked error");
}),
}));
describe('useNavigateMFE', () => {
it('should enter the catch block when an error occurs', () => {
// Spy on console.log to verify it was called
const consoleSpy = jest.spyOn(console, 'log').mockImplementation(() => {});
// Act: Call useNavigateMFE to trigger the catch block
useNavigateMFE();
// Assert: Check that console.log was called
expect(consoleSpy).toHaveBeenCalledWith(expect.any(Error));
// Cleanup
consoleSpy.mockRestore();
});
});
问题 即使模拟的实现抛出错误,catch 块也不会被触发。如何确保我的测试覆盖了 catch 块?
附加信息 我正在使用 Jest 进行测试。 该代码是 React 项目的一部分。 任何意见或建议将不胜感激!
为了回答你的问题,通过查看代码,我相信你的方法应该有效,尽管当然,要抛出错误,你需要 both 模拟
window.hfe
为 null
并模拟 useNavigate
为抛出一个错误。目前尚不清楚你是否这样做了。另外,为了通过测试,您需要将 "An error occurred:"
添加到 .toHaveBeenCalledWith
。
但是
您需要重新考虑测试方法。基本上,您描述的测试是测试是否
try {
throw new Error();
} catch (e) {
console.log(e);
}
打印错误。是的,确实如此。它在语言规范中,您无需担心。
其他想法
useNavigate
执行此操作。一个有效的替代方案是const nav = useNavigate();
navigate = window?.hfe?.testdevice
? window?.hfe?.histr
: nav;
navigate
作为函数外部的模块作用域变量违反了这一点,并且很难推断另一个函数是否也要修改该变量。最好从函数返回navigate
。const nav = useNavigate();
return window?.hfe?.testdevice
? window?.hfe?.histr
: nav;