如何在ReactJS项目中Mock AWS Auth.signUp API并测试两种响应
用Jest和react-testing-library Mock AWS Cognito Auth.signUp,测试注册成功/失败场景
第一步:Mock AWS Amplify的Auth模块
首先在测试文件顶部Mock aws-amplify中的Auth对象,让Jest接管signUp方法的实现:
import { Auth } from 'aws-amplify'; // Mock Auth模块,替换signUp为Jest spy函数 jest.mock('aws-amplify', () => ({ Auth: { signUp: jest.fn() } }));
测试场景1:注册成功(Promise resolved)
让Auth.signUp返回成功的Promise,验证注册流程正常执行:
it('注册成功时应正确调用Auth.signUp并处理结果', async () => { // 定义模拟的Cognito返回用户数据 const mockUser = { user: { username: 'test@PWDil.com', attributes: { email: 'test@PWDil.com' } } }; // 设置signUp返回成功的Promise Auth.signUp.mockResolvedValue(mockUser); const handleRegisterSpy = jest.fn(); const userCredentials = { email: 'test@PWDil.com', pwd: 'SignUp@2022' }; const { getByTestId } = render( <Authentication screen={1} setScreen={jest.fn()} handleRegister={handleRegisterSpy} // 注意:传递函数引用,不要直接调用 /> ); const emailInput = getByTestId("email"); const passwdInput = getByTestId("pwd"); const signUpBtn = getByTestId("btnSignUpField"); // 输入账号密码 fireEvent.change(emailInput, { target: { value: userCredentials.email } }); fireEvent.change(passwdInput, { target: { value: userCredentials.pwd } }); // 触发注册按钮点击 fireEvent.click(signUpBtn); // 等待异步操作完成后验证 await waitFor(() => { // 验证Auth.signUp被正确调用,参数匹配输入的账号密码 expect(Auth.signUp).toHaveBeenCalledWith(userCredentials.email, userCredentials.pwd); // 验证注册回调被触发(如果你的组件逻辑中会调用handleRegister) expect(handleRegisterSpy).toHaveBeenCalled(); }); });
测试场景2:注册失败(Promise rejected)
让Auth.signUp返回失败的Promise,验证错误被正确捕获处理:
it('注册失败时应捕获错误并执行错误逻辑', async () => { // 定义模拟的错误信息 const mockError = new Error('该邮箱已被注册'); // 设置signUp返回失败的Promise Auth.signUp.mockRejectedValue(mockError); // 监听console.log,验证错误被打印 const consoleSpy = jest.spyOn(console, 'log').mockImplementation(); const handleRegisterSpy = jest.fn(); const userCredentials = { email: 'test@PWDil.com', pwd: 'SignUp@2022' }; const { getByTestId } = render( <Authentication screen={1} setScreen={jest.fn()} handleRegister={handleRegisterSpy} /> ); const emailInput = getByTestId("email"); const passwdInput = getByTestId("pwd"); const signUpBtn = getByTestId("btnSignUpField"); fireEvent.change(emailInput, { target: { value: userCredentials.email } }); fireEvent.change(passwdInput, { target: { value: userCredentials.pwd } }); fireEvent.click(signUpBtn); await waitFor(() => { // 验证Auth.signUp被调用 expect(Auth.signUp).toHaveBeenCalledWith(userCredentials.email, userCredentials.pwd); // 验证错误被打印(对应你代码中的console.log(e)) expect(consoleSpy).toHaveBeenCalledWith(mockError); }); // 恢复console.log的原始实现 consoleSpy.mockRestore(); });
测试代码中的几个修正点
- 不要直接调用
handleRegisterSpy(),应该传递函数引用handleRegisterSpy给组件 - 变量名要保持一致:你定义了
user.email,但原测试中用了user.emailValue,会导致输入值错误 - 所有涉及异步操作的断言,必须用
await waitFor()包裹,确保Promise执行完成后再验证结果
内容的提问来源于stack exchange,提问作者Tarek
相关产品推荐
相关产品推荐

