在我们的项目中,我们使用react-oidc-context(它使用oidc-client-ts)对用户进行身份验证。
react-oidc-context公开useAuth
,其中包含诸如isAuthenticated
、isLoading
、验证时的user
对象等信息。
为了完全测试我的组件,我需要在每个测试中用不同的返回值来模拟它。通常我会用jest.spyOn
和mockImplementation
来设置正确的测试条件。
然而,useAuth
返回的(嵌套)属性的数量相当大,而且将来可能会发生变化,所以我不想把所有的东西都输入出来,我只想传递我关心的属性,但typescript不允许这样做。
一个例子:
// Login.tsx
// AuthProvider has redirect_uri set that points back to this file
import { Button } from 'react-components';
import { useAuth } from 'react-oidc-context';
import { Navigate } from 'react-router-dom';
const Login = (): JSX.Element => {
const auth = useAuth();
if (auth.isAuthenticated) {
return <Navigate to="/dashboard" replace />;
}
return (
<main style={{ display: 'flex', justifyContent: 'center', paddingTop: '5rem' }}>
<Button variant="secondary" onClick={() => auth.signinRedirect()}>
Sign in
</Button>
</main>
);
};
export default Login;
个字符
在上面的代码中,打字机会抱怨mockImplementation与AuthContextProps不匹配。这是正确的!缺少12个直接属性和更多的深层嵌套属性。
如果我试图欺骗TS:
// Login.test.tsx with type casting
import { renderWithProviders, screen } from '@test/utils';
import * as oidc from 'react-oidc-context';
import Login from '../Login';
describe('Login view', () => {
it('Shows a login button', () => {
jest.spyOn(oidc, 'useAuth').mockImplementation(
() =>
({
isAuthenticated: false,
}) as oidc.AuthContextProps // <--- NEW
);
renderWithProviders(<Login />);
expect(screen.findByRole('button', { name: 'Sign in' }));
});
});
型
现在我得到一个运行时错误:TypeError: Cannot redefine property: useAuth
废话了
我试过许多不同的嘲笑技巧,但在某个时候都失败了。
回到绘图板上,我试图放弃整个嘲笑的事情,只是设置一个提供者与假证书。基本上是我做的React路由器。
这将适用于未验证状态,但据我所知,我无法伪造已验证状态。
import { renderWithProviders, screen } from '@test/utils';
import Login from '../Login';
describe('Login view', () => {
it('Shows a login button', () => {
renderWithProviders(
<AuthProvider
{...{
authority: 'authority',
client_id: 'client',
redirect_uri: 'redirect',
}}
>
<Login />
</AuthProvider>
);
expect(screen.findByRole('button', { name: 'Sign in' }));
});
});
型
所以我能想到的最后一件事就是编写一些helper来为useAuth
生成一个满足TS的大的返回对象。
就像我说的,我一直在推迟,因为这似乎不是很未来的证据。
有谁知道怎么把它修好,弄得漂亮一点吗?
1条答案
按热度按时间inkz8wg91#
睡了一个好觉之后,我终于找到了一个方法。灵感来自这个答案:https://stackoverflow.com/a/73761102/1783174
字符串
在jest-setup中,我为
useAuth
创建了默认的模拟返回值作为参考,下面是我们测试的Login组件文件
型