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

如何使用React Native Testing Library测试Yup .test()异步校验方法

解决方案

下面是导致问题的几个核心原因及对应修改方式:

1. 修复Yup异步校验函数的this指向问题

这是最核心的故障原因:你在Yup的test方法中使用了箭头函数作为校验回调,箭头函数没有独立的this指向,无法拿到Yup的test上下文,导致this.createError调用直接报错,而你代码中catch块没有做任何错误处理,错误被静默吞掉,Yup会认为校验通过,自然不会展示错误。
将Schema中的test回调修改为普通函数即可:

const schema = yup.object().shape({
  username: Yup.string()
    .required('必填')
    .min(3, '长度过短')
    .max(15, '长度过长')
    .matches(/^[A-Za-z0-9_-]*$/, '不允许特殊符号')
    .test(
      'unique-username', 
      '用户名已被使用', 
      // 替换箭头函数为普通function
      async function (value: string | undefined) {
        if(value){
          try {
            const res = await checkUserHandleExist(value);
            const data = res.data;
            if (data.error) {
              return this.createError({message: "校验用户名时出错"});
            } else {
              if (data.is_user_handle_exists) {
                return this.createError({message: "用户名已被使用"});
              }
              return true;
            }
          } catch (error) {
            return this.createError({message: "校验用户名时出错"});
          }
        }
        return true;
      }
    )
})

2. 补全测试中的事件触发逻辑

Formik默认的异步校验触发时机是输入框失焦时,你当前测试代码只触发了changeText输入事件,没有触发失焦事件,异步校验根本不会执行。输入完成后补充失焦触发:

fireEvent.changeText(usernameField, 'kenchoong')
// 新增失焦事件,触发异步校验
fireEvent.blur(usernameField)

3. 等待异步流程执行完成

异步校验需要等待接口请求、校验逻辑执行、页面渲染的完整流程,不能用同步的queryByText立刻查询结果,换成自带等待能力的findByText即可:

// findByText默认最长等待1秒,会自动轮询查询元素
const errorMsg = await findByText(/用户名已被使用/i)
expect(errorMsg).toBeTruthy()

如果你偏好使用waitFor,写法如下:

await waitFor(() => {
  expect(getByText(/用户名已被使用/i)).toBeTruthy()
})

4. 确认Mock接口配置正确

如果你使用MSW做接口Mock,需要确认Mock的请求方法、路径、参数和checkUserHandleExist实际发起的请求完全一致,避免Mock未命中导致接口请求失败被catch吞掉,校验直接通过。可以在校验函数中加日志确认是否拿到了Mock返回的is_user_handle_exists: true结果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 13:30:02