You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Jest登录单元测试异常:Login API未返回Promise问题排查

登录页面单元测试问题排查:调用login API未返回Promise导致流程中断

我开发的登录页面功能正常,但使用Jest编写该模块单元测试时出现问题:调用login API未返回Promise,导致无法打印console.log("after login");日志,后续流程也无法执行。以下是相关代码:

React业务代码

validateAll(formData, rules, message).then(async () => {
    dispatch(setLoading(true))

    console.log("before login");    
    const login = await authApi.login(app, email, password)
    console.log("after login");    

    if (login && login.error && login.error !== null) {
        dispatch(setLoading(false))
        ToastAlert({ msg: login.error.error || login.error.message, msgType: 'error' });
        dispatch(setToken(''))
    } else {
        console.log("done");
        dispatch(setToken(login.data._accessToken))
        setSuccess(true)
        dispatch(setLoading(false))
        //router.replace("/");
        ToastAlert({ msg: 'You have successfully logged in', msgType: 'success' });
    }
})

authApi代码

import { resolve } from "./resolve";
import * as Realm from "realm-web";
function auth() {
    const register = async (app: any, data: object) => {
        return await resolve(
            app.emailPasswordAuth.registerUser(data)
                .then((response: any) => response)
        )
    }
    const login = async (app: any, email: string, password: string) => {
        const credentials = await Realm.Credentials.emailPassword(email, password);
        return await resolve(
            app.logIn(credentials)
                .then((response: any) => response)
        )
    }
    const confirmUser = async (app: any, data: object) => {
        return await resolve(
            app.emailPasswordAuth.confirmUser(data)
                .then((response: any) => response)
        )
    }
    const logout = async (app: any) => {
        return await resolve(
            app.currentUser.logOut()
                .then((response: any) => response)
        )
    }
    return {
        register,
        login,
        confirmUser,
        logout
    }
}
const authApi = auth();
export default authApi;

Jest测试代码

test('login with correct username and password', async () => {
    const initialState = {
        email: '',
        password: '',
        error: {
            email: "",
            password: ""
        },
    };
    const mockStore = configureStore();
    let store;
    store = mockStore(initialState);
    const { getByText,getByLabelText } = render(
        <Provider store={store}>
            <Authenticate  />
        </Provider>
    );
    // fill out the form
    fireEvent.change(screen.getByLabelText('Email'), {
        target: {value: '***@gmail.com'},
    })
    fireEvent.change(screen.getByLabelText(/Parola/i), {
        target: {value: '****@123'},
    })
    const loginAwait = screen.getByText(/Authentificare/i);      
    await fireEvent.click(loginAwait)

    // wait for the error message
    const alert = await screen.findByRole('alert')
    expect(alert).toHaveTextContent(/You have successfully logged in/i)
})

解决方案

1. Mock authApi的login方法

测试中不要调用真实的Realm API,而是mock authApi模块,让login方法返回一个已resolve的Promise,模拟成功场景:

// 在测试文件顶部引入并mock
import authApi from '../path/to/authApi';
jest.mock('../path/to/authApi', () => ({
  login: jest.fn().mockResolvedValue({
    data: { _accessToken: 'mock-token' }
  })
}));

注意替换../path/to/authApi为实际文件路径。

2. 确保异步流程被正确等待

fireEvent.click不会等待内部异步操作完成,建议结合waitFor来等待UI更新:

fireEvent.click(loginAwait);
// 等待alert出现并验证内容
await waitFor(() => {
  expect(screen.getByRole('alert')).toHaveTextContent(/You have successfully logged in/i);
});

3. 检查resolve函数的实现

确认resolve函数正确封装Promise,确保它返回Promise对象,示例正确实现:

// resolve.js
export function resolve(promise) {
  return promise
    .then(data => ({ data }))
    .catch(error => ({ error }));
}

如果resolve函数没有正确返回Promise,会导致await authApi.login()无法等待结果。

4. 验证mock调用是否生效

添加断言确保login方法被正确调用:

// 在测试末尾添加
expect(authApi.login).toHaveBeenCalledWith(
  expect.anything(), 
  '***@gmail.com', 
  '****@123'
);

内容的提问来源于stack exchange,提问作者Nikul Panchal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 13:15:17