2

我正在用 React Native 构建一个应用程序。我们最近开始在应用程序中使用 TypeScript,我的任务是迁移单元测试。有一个测试奇迹般地失败了。

该应用程序有一个<LoginForm />使用Formik

//... imports

export interface FormValues {
  email: string;
  password: string;
}

export interface Props {
  navigation: NavigationScreenProp<any, any>;
}

export default class LoginForm extends Component<Props, object> {
  handleSubmit = (values: FormValues, formikBag: FormikActions<FormValues>) => {
    // ... api calls and stuff
  };

  renderForm = ({
    values,
    handleSubmit,
    setFieldValue,
    touched,
    errors,
    setFieldTouched,
    isValid,
    isSubmitting
  }: FormikProps<FormValues>) => (
    <View style={styles.container}>
      // ... two inputs and a button
    </View>
  );

  render() {
    return (
      <Formik
        initialValues={{ email: "", password: "" }}
        onSubmit={(values: FormValues, formikBag: FormikActions<FormValues>) =>
          this.handleSubmit(values, formikBag)
        }
        validationSchema={<some_schema>}
        render={(formikBag: FormikProps<FormValues>) => this.renderForm(formikBag)}
      />
    );
  }
}

这是单元测试查找 Function as Child 的方式renderForm()

describe("renderForm", () => {
  let formWrapper: ShallowWrapper;
  beforeEach(() => {
    let formikBagMock: any = {
      values: { email: "Test Email", password: "testpassword" },
      handleSubmit: jest.fn(),
      setFieldValue: jest.fn(),
      errors: { email: "Test error", password: "" },
      touched: { email: true, password: false },
      setFieldTouched: jest.fn(),
      isValid: false,
      isSubmitting: false
    };
    formWrapper = shallow(wrapper.instance().renderForm(formikBagMock));
  });

  it("should render a <View />", () => {
    expect(formWrapper.find("View")).toHaveLength(1);
  });

  it("should render two <Input />", () => {
    expect(formWrapper.find("Input")).toHaveLength(2);
  });

  it("should render a <Button />", () => {
    expect(formWrapper.find("Button")).toHaveLength(1);
  });

  describe("styling", () => {
    it("should give the <View /> the 'container' style", () => {
      expect(formWrapper.find(View).prop("style")).toEqual(styles.container);
    });
  });
});

问题是,当这个测试通过时,.js它在.tsx.

The error thrown looks like this:

 ● LoginForm › rendering › renderForm › should render a <Button />

    expect(received).toHaveLength(length)

    Expected value to have length:
      1
    Received:
      {Symbol(enzyme.__root__): {Symbol(enzyme.__root__): [Circular], Symbol(enzyme.__unrendered__): <Component style={{"alignItems": "center", "flex": 1, "justifyContent": "space-evenly"}}><Input autoCapitalize="none" editable={true} errorMessage="Test error" keyboardType="email-address" onBlur={[Function onBlur]} onChangeText={[Function onChangeText]} placeholder="Email address" value="Test Email" /><Input autoCapitalize="none" editable={true} onBlur={[Function onBlur]} onChangeText={[Function onChangeText]} placeholder="Password" secureTextEntry={true} value="testpassword" /><Button TouchableComponent={[Function anonymous]} buttonStyle={{"backgroundColor": "#DC4F19"}} clear={false} containerStyle={{"paddingVertical": 5, "width": "33%"}} disabled={true} disabledStyle={{"backgroundColor": "#DC4F19", "opacity": 0.3}} disabledTitleStyle={{"color": "white"}} iconRight={false} loading={false} loadingProps={{"color": "white", "size": "large"}} onPress={[Function mockConstructor]} raised={false} title="Log In" titleStyle={{"color": "white"}} /></Component>, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateError": [Function simulateError], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__node__): {"instance": null, "key": undefined, "nodeType": "function", "props": {"children": [Function anonymous]}, "ref": null, "rendered": [Function anonymous], "type": {"$$typeof": Symbol(react.context), "Consumer": [Circular], "Provider": {"$$typeof": Symbol(react.provider), "_context": [Circular]}, "_calculateChangedBits": null, "_currentRenderer": null, "_currentRenderer2": null, "_currentValue": false, "_currentValue2": false, "unstable_read": [Function bound readContext]}}, Symbol(enzyme.__nodes__): [{"instance": null, "key": undefined, "nodeType": "function", "props": {"children": [Function anonymous]}, "ref": null, "rendered": [Function anonymous], "type": {"$$typeof": Symbol(react.context), "Consumer": [Circular], "Provider": {"$$typeof": Symbol(react.provider), "_context": [Circular]}, "_calculateChangedBits": null, "_currentRenderer": null, "_currentRenderer2": null, "_currentValue": false, "_currentValue2": false, "unstable_read": [Function bound readContext]}}], Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true, "lifecycles": {"componentDidUpdate": {"onSetState": true}, "getDerivedStateFromProps": true, "getSnapshotBeforeUpdate": true, "setState": {"skipsComponentDidUpdateOnNullish": true}}}}, "attachTo": undefined, "hydrateIn": undefined}}, Symbol(enzyme.__unrendered__): null, Symbol(enzyme.__renderer__): {"batchedUpdates": [Function batchedUpdates], "getNode": [Function getNode], "render": [Function render], "simulateError": [Function simulateError], "simulateEvent": [Function simulateEvent], "unmount": [Function unmount]}, Symbol(enzyme.__node__): undefined, Symbol(enzyme.__nodes__): [], Symbol(enzyme.__options__): {"adapter": {"options": {"enableComponentDidUpdateOnSetState": true, "lifecycles": {"componentDidUpdate": {"onSetState": true}, "getDerivedStateFromProps": true, "getSnapshotBeforeUpdate": true, "setState": {"skipsComponentDidUpdateOnNullish": true}}}}, "attachTo": undefined, "hydrateIn": undefined}}
    received.length:
      0

      61 |
      62 |       it("should render a <Button />", () => {
    > 63 |         expect(formWrapper.find("Button")).toHaveLength(1);
         |                                            ^
      64 |       });
      65 |
      66 |       describe("styling", () => {

怎么可能,Enzyme 突然找不到节点了?我什至尝试导入 components ViewButtonInput直接将其传递给find()而不是字符串,但它并没有改变任何东西。我究竟做错了什么?

4

1 回答 1

0

您可以formWrapper.debug().js.tsx文件中进行比较,看看有什么不同。

由于您正在使用Shallow Rendering,您可能需要dive()点击Button. 用于console.log(formWrapper.debug())查看渲染的内容。

如果仅View呈现,请尝试:expect(formWrapper.dive().find("Button")).toHaveLength(1)

于 2021-02-09T16:25:59.317 回答