Reactjs 使用测试库和jest的React组件引发的测试错误
按照本文解释的Kent C Dodds的提供者模式,我有一个上下文提供者组件和一个钩子来使用该上下文 钩子防止在提供者之外使用它Reactjs 使用测试库和jest的React组件引发的测试错误,reactjs,jestjs,react-testing-library,react-context,Reactjs,Jestjs,React Testing Library,React Context,按照本文解释的Kent C Dodds的提供者模式,我有一个上下文提供者组件和一个钩子来使用该上下文 钩子防止在提供者之外使用它 export function useUser() { const { user } = useContext(UserContext) || {}; const { switchUser } = useContext(SwitchUserContext) || {}; if (!user || !switchUser) { throw new E
export function useUser() {
const { user } = useContext(UserContext) || {};
const { switchUser } = useContext(SwitchUserContext) || {};
if (!user || !switchUser) {
throw new Error('Cannot use `useUser` outside of `UserProvider`');
}
return { user, switchUser };
}
为了测试场景,我创建了一个TestComponent
,并在其中使用useUser
钩子
function TestComponent() {
const { user, switchUser } = useUser();
return (
<>
<p>User: {user.name}</p>
<button onClick={switchUser}>Switch user</button>
</>
);
}
函数TestComponent(){
const{user,switchUser}=useUser();
返回(
用户:{User.name}
交换机用户
);
}
我这样测试它
test('should throw error when not wrapped inside `UserProvider`', () => {
const err = console.error;
console.error = jest.fn();
let actualErrorMsg;
try {
render(<TestComponent />);
} catch(e) {
actualErrorMsg = e.message;
}
const expectedErrorMsg = 'Cannot use `useUser` outside of `UserProvider`';
expect(actualErrorMsg).toEqual(expectedErrorMsg);
console.error = err;
});
test('未包装在'UserProvider'中时应引发错误,()=>{
const err=console.error;
console.error=jest.fn();
让actualErrorMsg;
试一试{
render();
}捕获(e){
actualErrorMsg=e.message;
}
const expectedErrorMsg='不能在'UserProvider'之外使用'useUser';
expect(actualErrorMsg).toEqual(expectedErrorMsg);
console.error=err;
});
我目前必须模拟控制台。错误,然后在测试结束时将其设置为原始值。它起作用了。但我想让它更具声明性,更简单。有一个好的模式来实现它吗?
有什么用的吗
我对此有一个解释,上面的代码可以在UserContext.js
和UserContext.test.js
中找到
注意:测试可以在codesandbox自身的
测试选项卡下运行。您可以这样做
test('should throw error when not wrapped inside `UserProvider`', () => {
component.useUser = jest.fn().mockRejectedValue(new Error('Cannot use `useUser` outside of `UserProvider`'));
let actualErrorMsg;
try {
render(<TestComponent />);
} catch(e) {
actualErrorMsg = e.message;
}
const expectedErrorMsg = 'Cannot use `useUser` outside of `UserProvider`';
expect(actualErrorMsg).toEqual(expectedErrorMsg);
});
test('未包装在'UserProvider'中时应引发错误,()=>{
component.useUser=jest.fn().mockRejectedValue(新错误('不能在'UserProvider'之外使用'useUser');
让actualErrorMsg;
试一试{
render();
}捕获(e){
actualErrorMsg=e.message;
}
const expectedErrorMsg='不能在'UserProvider'之外使用'useUser';
expect(actualErrorMsg).toEqual(expectedErrorMsg);
});
正如您已经提到的,有expect().toThrow()
:)
因此,在你的情况下:
test(“未包装在`UserProvider`'中时应引发错误,()=>{
预期(()=>render())
.toThrow(“不能在`UserProvider`之外使用`useUser`”);
});
关于控制台。错误
:
目前,按照设计,无法关闭默认错误日志。
如果要隐藏错误,仍然需要模拟控制台.error
当您模拟诸如console.error
之类的函数时,您希望在每次
回调后在中还原它们,以便在测试失败时也还原它们。这似乎不起作用。我得到Error:Uncaught[错误:无法在UserProvider
]之外使用
useUser`给你:)你是对的,测试确实通过了:)仍然记录了一个未捕获的错误。试一试不管用。没有办法捕捉测试中的错误吗?expect(fn).toThrow()捕捉错误。但是在您捕获它之前,它已经被jsdom记录到测试环境中的控制台中。我能够通过如下方式模拟它来抑制console.log错误:const consoleErrorFn=jest.spyOn(console,'error').mockImplementation(()=>jest.fn())代码>如果你沿着那条路走,别忘了开玩笑。restoreMocks()
。不确定这里有什么组件?