React Native:在开玩笑的单元测试中更新上下文 api 值
React Native : Update context api values in jest unit tests
我正在编写单元测试以验证具有少量文本输入和自定义下拉字段的 React 本机表单。我正在使用 jest
和 react-native-testing-library
。表单在提交 btn 时被验证。表单值保存到上下文(使用 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();
});
})
所以,我的问题是,为什么上下文没有更新?这是更新上下文的错误方法吗?
注意:我不是在模拟上下文,而是更喜欢这种方式,以使用实际的上下文。
实际上问题是我犯的一些错误,而不是测试库的任何怪癖。
- 上下文正在更新,只是我使用的全局变量有旧值,为了获得更新的上下文值,我不得不再次访问上下文,如
form.getByTestId("context_exposer").props
。formValues
- 我在第一个文本输入中输入了无效文本("valid input text"/* 无效 :) */),停止了验证。
感谢您的宝贵时间。
我正在编写单元测试以验证具有少量文本输入和自定义下拉字段的 React 本机表单。我正在使用 jest
和 react-native-testing-library
。表单在提交 btn 时被验证。表单值保存到上下文(使用 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();
});
})
所以,我的问题是,为什么上下文没有更新?这是更新上下文的错误方法吗?
注意:我不是在模拟上下文,而是更喜欢这种方式,以使用实际的上下文。
实际上问题是我犯的一些错误,而不是测试库的任何怪癖。
- 上下文正在更新,只是我使用的全局变量有旧值,为了获得更新的上下文值,我不得不再次访问上下文,如
form.getByTestId("context_exposer").props
。formValues
- 我在第一个文本输入中输入了无效文本("valid input text"/* 无效 :) */),停止了验证。
感谢您的宝贵时间。