React Native:在开玩笑的单元测试中更新上下文 api 值
Posted
技术标签:
【中文标题】React Native:在开玩笑的单元测试中更新上下文 api 值【英文标题】:React Native : Update context api values in jest unit tests 【发布时间】:2020-02-15 13:38:37 【问题描述】:我正在编写单元测试,以验证带有少量文本输入和自定义下拉字段的反应原生表单。我正在使用jest
和react-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 项目中开玩笑。如何将重复模块列入黑名单或删除?