React Native:在开玩笑的单元测试中更新上下文 api 值

Posted

技术标签:

【中文标题】React Native:在开玩笑的单元测试中更新上下文 api 值【英文标题】:React Native : Update context api values in jest unit tests 【发布时间】:2020-02-15 13:38:37 【问题描述】:

我正在编写单元测试,以验证带有少量文本输入和自定义下拉字段的反应原生表单。我正在使用jestreact-native-testing-library。该表格在提交 btn press 时得到验证。表单值被保存到上下文并从上下文中访问(使用 useReducer() 钩子)。

我无法模拟Dropdown 字段的输入值,所以要跳过它,我想通过向上下文发送一个随机有效值来设置该字段的上下文值,用act() 包裹,这样验证就不会停在那里,而是继续验证下一个TextInput

但是,当我记录上下文值时,它仍然像以前一样保持不变,并且验证与之前的字段一起停止。

ContextProvider.js

export function FormContextProvider(children)
  const [formValues, dispatchFormValues] = useReducer(
    formValuesReducer,
    individualFormInitialState
  );

  return <FormContext.Provider value=formValues,dispatchFormValues> 
  children</FormContext.Provider>




function formValuesReducer(state, action) 
  switch (action.type) 
    case "FIELD_VALUE":
      return  ...state, ...action.payload ;  
    default:
      return state;
  

FormComponent.js


export default class FormComponent extends React.Component 
  render() 
  const formContext = useContext();
  const [t1Err, setT1Err] = useState("");
  const [t2Err, t2Err] = useState("");
  const [dpErr, dpErr] = useState("");

  const validateAndSubmit = ()=>
   //some validations...

  

  return (
      <View style=styles.container>
        <TextInput
        value="whatever"
        onChange=(val)=>formContext.dispatch(
          type:"FORM_VALUE",
          payload:t1:val
        )
        ></TextInput>
      <DropdownSelect 
        some=props
        onChange=(val)=>formContext.dispatch(
          type:"FORM_VALUE",
          payload:dp:val
        )
       value=formContext.formValues.dp
     />
     <TextInput
        value="whatever"
        onChange=()=>formContext.dispatch(
          type:"FORM_VALUE",
          payload:t2:val
        )
        ></TextInput>
      t2Err ? <InputError>"This field is mandatory"</InputError>:<></>
      <Button onPress=validateAndSubmit></Button>
      </View>
    );
  



FormComponent.test.js

   const form = (
    <FormContextProvider>
      <FormContext.Consumer>
        props => 
          return (
            <Text testID="context_exposer" ...props>
              Exposes Context
            </Text>
          );
        
      </FormContext.Consumer>
      <FormComponent navigation=navigation />
    </FormContextProvider>
   );

    //expose the context for tests
    const 
     dispatchFormValues,
     formValues
     = form.getByTestId("context_exposer").props;


   describe("form validations",()=>

     it("t2 validations",done=>

        fireEvent.changeText(t1, "valid input text");
        act(
          ()=>dispatchFormValues(
            type: "FIELD_VALUE",
            payload:  dp: 200 
          )
        );
        console.log("formValues", formValues.dp);/* *** still logs old values *** */
        fireEvent.press(submitBtn);
        //t2 input is empty and required, so on submitbtnPress, should show an error msg.
        const t2Err = t2Input.findByType(InputError); 

        expect(t2Err).not.toBeNull();//test fails since no errorMsg element is showing.
        done();

   );


  )

所以,我的问题是,为什么上下文不更新?这是更新上下文的错误方式吗?

注意:我不是在模拟上下文,而是更喜欢这种方式来使用实际上下文。

【问题讨论】:

【参考方案1】:

实际上问题是我犯了一些错误,而不是测试库的任何怪癖。

    上下文正在更新,只是我使用的全局变量具有旧值,为了获取更新后的上下文值,我必须再次访问上下文,如form.getByTestId("context_exposer").props.formValues 我在第一个文本输入中输入了无效文本("valid input text"/* not valid :) */),从而自行停止验证。

感谢您的宝贵时间。

【讨论】:

以上是关于React Native:在开玩笑的单元测试中更新上下文 api 值的主要内容,如果未能解决你的问题,请参考以下文章

用于 react-native 的 Code Push 打破玩笑测试

调度程序没有在开玩笑的单元测试中注册回调

在 React-Native 项目中开玩笑。如何将重复模块列入黑名单或删除?

如何对 fetch 完成后呈现的 React 组件进行单元测试?

使用玩笑的反应单元测试失败

如何在带有 Jest 的 react-native 中使用模拟的 fetch() 对 API 调用进行单元测试