0

我有一个 Formik,它是这样的:

<Formik
   initialValues={initialValue}
   validationSchema={schema} // Here I set to the schema below. 
   onSubmit={handleBasicSubmit}
>

<FormControl isRequired isInvalid={"username" in errors}> // here if the error from schema it will shown 
     <FormControl.Label>Username</FormControl.Label>
       <Input
         p={2}
         onChangeText={handleChange("username")}
         placeholder="Preferred username"
         value={values.username}
      />
      <FormControl.ErrorMessage>
         {errors.username}
       </FormControl.ErrorMessage>
    </FormControl>

</Formik>

当在字段中输入用户名时,模式将与服务器检查是否username已经通过调用checkUserHandleExist函数内部的.test()函数来获取。

是的架构:

const schema = yup.object().shape({
   username: Yup.string()
        .required('Required')
        .min(3, 'Too short')
        .max(15, 'Long')
        .matches(/^[A-Za-z0-9_-]*$/, 'No symbol')
        .test(
          'unique-username', 
          'Already used', 
           async (value: string | undefined) =>  {
             if(value){
              try {
               const res = await checkUserHandleExist(value);

               const data = res.data;

               if (data.error) {
                 // @ts-expect-error
                 return this.createError("Have problem verify username");
               } else {
                 if (data.is_user_handle_exists) {
                   // @ts-expect-error
                   return this.createError("Already used"); // the phase should be on screen 
                 }
                 else {
                   return true;
                 }
               }
             } catch (error) { }
            }
        }
        )

})

为了使用 React-Native-testing-library 对其进行测试,这是我的测试:

it('Username enter is existed after check from server, display error', async () => {
      // here mock the API method for checkUsernameExisted 
      rest.get(API_URL + "/invite", (req, res, ctx) => {
        return res(
          ctx.status(200),
          ctx.json({
            is_user_handle_exists: true  // Here mock the result is true 
          })
        )
      })
      
      const { getByText, getByPlaceholderText, queryByText } = render( 
            <UserBasicDetails />
      );
    
      const usernameField = getByPlaceholderText('Preferred username, macam Twitter or Ig')

      fireEvent.changeText(usernameField, 'kenchoong')
      const button = getByText('Continue')
      
      
      const errorMsg = queryByText(/Already used/i) // here Already used should be existed 
      expect(errorMsg).not.toBeNull()  
     
    })

正如您在此处看到的,我模拟了 API 方法以true作为结果返回(在 Yup 测试函数中)。

然后errorMsg应该根据我的代码存在。

现在问题

当我queryByText为这Already used句话时,它总是得到这个消息Error: expect(received).not.toBeNull()

我试过的:

  1. 我认为我应该wait显示错误消息,所以我尝试了这个:
await waitFor(() => {
        const errorMsg = queryByText(/Already used/i) // here Already used should be existed 
        expect(errorMsg).not.toBeNull()  
      })

有同样的错误。

  1. 我也尝试过使用getByTextfindByText也有这个错误 Error: expect(received).not.toBeNull()

  2. 我什至尝试不使用waitFor

const errorMsg = await findByText(/Already used/i) // here Already used should be existed 
expect(errorMsg).not.toBeNull()

我不知道为什么会这样。既然我已经waitFor它应该等到errorMsg出现。但它没有。我的所有其他测试用例max和Yup 模式都通过了,只是min没有通过。不知道为什么。matchestest

请提供一些帮助。提前致谢。

4

0 回答 0