如何解决如何使用带有 jest + MSW
我有一个组件,我很难弄清楚如何编写使用 Jest 和 MSW 的测试。
它是一个“AuthProvider”,用于初始化 keycloak-js 并呈现子项。
我编写了一个测试来检查 children
是否正确呈现。
我想测试以下场景:
- 它应该渲染儿童(这个有效)
- 它应该初始化keycloak(调用keycloak.init)
- 它应该向我们的 SSO 端点发出一个 post 请求(在 MSW 中命中一个休息模拟)
- 它应该使用“onReady”事件调用
onKeycloakEvent
- 它应该调用
login
- 它应该调用
onKeycloakTokens
(带有预期的令牌) - 它应该设置
user
(具有预期的用户名和角色) - 它应该设置
authToken
(带有预期的令牌) - 当使用“onTokenExpired”事件调用
login
时,它应该调用onKeycloakEvent
我已经安装并设置了 https://github.com/SectorLabs/keycloak-mock
以使用 nock
处理请求。
但是当涉及到如何等待这些事件被调用时,我完全陷入困境,因为 DOM 中没有任何变化。
一旦子节点渲染,测试立即通过,而无需等待 keycloak 甚至尝试初始化。
我将如何强制 jest 等待组件内部调用的函数或 keycloak 初始化?
我试图模拟 keycloak.init 并期待 2 个断言,但没有成功。
import React,{ useState } from 'react'
import { ReactKeycloakProvider } from '@react-keycloak/web'
import keycloak from 'src/lib/keycloak'
import { IDP_HINT } from 'src/common/constants'
import { useAtom,useUpdateAtom,authTokenAtom,userAtom } from 'src/atoms'
type KeycloakAuthProviderProps = {
children: React.ReactNode
}
const login = () => keycloak.login({ IDP_HINT })
const KeycloakAuthProvider = ({ children }: KeycloakAuthProviderProps) => {
const [calledLogin,setCalledLogin] = useState(false)
const [authToken,setAuthToken] = useAtom(authTokenAtom)
const setUser = useUpdateAtom(userAtom)
const onKeycloakEvent = (event: string,error: any) => {
console.log('onKeycloakEvent',event)
if (event === 'onReady') {
if (keycloak && !calledLogin && !authToken) {
// on first load,automatically attempt a keycloak login.
login()
setCalledLogin(true)
}
} else if (keycloak && event === 'onTokenExpired') {
login()
}
if (error) console.error(error)
}
const onKeycloakTokens = (tokens: any) => {
console.log('onKeycloakTokens',tokens)
if (keycloak?.tokenParsed && keycloak.tokenParsed?.realm_access?.roles) {
setUser({
userName: keycloak.tokenParsed.preferred_username,roles: keycloak.tokenParsed.realm_access.roles,})
}
const authToken = tokens.token
setAuthToken(authToken)
}
return (
<ReactKeycloakProvider
initOptions={{ flow: 'implicit',onLoad: 'check-sso' }}
onEvent={onKeycloakEvent}
onTokens={onKeycloakTokens}
authClient={keycloak}
>
{children}
</ReactKeycloakProvider>
)
}
export default KeycloakAuthProvider
keycloak.init 模拟尝试(失败)
import React from 'react'
import { render,screen } from 'src/test/test-utils'
import AuthProvider from './AuthProvider'
import keycloak from './index'
// MISSING tests:
// - it should initialize keycloak (call keycloak.init)
// - it should make a post request to our SSO endpoint (hit a rest mock in MSW/nock)
// - it should call `onKeycloakEvent` with an "onReady" event
// - it should call `login`
// - it should call `onKeycloakTokens` (with expected tokens)
// - it should set `user` (with expected userName and roles)
// - it should set `authToken` (with expected token)
// - it should call `login` when `onKeycloakEvent` is called with an "onTokenExpired" event
test('AuthProvider initializes keycloak',() => {
expect.assertions(2); // attempt to make keycloak wait for init
keycloak.init = jest.fn() // mock keycloak.init
render(
<AuthProvider>
<div>test</div>
</AuthProvider>
)
const childElement = screen.getByText(/test/i)
expect(childElement).toBeInTheDocument()
expect(keycloak.init).toHaveBeenCalled(); // expect to have called keycloak
})
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。