jest test fails with refs and Form

Viewed 6214

I have a search bar component which looks like:

  render () {
    const { onChangeTextInput } = this.props
    return (
      <Form
        name="searchForm"
        ref={(ref) => {
          this.searchForm = ref
        }}
      >
        <TextInput
          noSpacing
          placeholder={t('search')}
          name="search"
          validate="text"
          icon={this.icon}
          onChangeTextCallback={() => {
            onChangeTextInput(this.searchForm.values)
          }}
        />
        )
      </Form>
    )
  }
}

I am using a shallow render and jest to run a unit test to test the following scenario"

  1. User types a character in text input
  2. a callback method gets fired which provides the user with the text as an argument.

The test I am running is stated as:

 test('SearchBar returns value on text change', () => {
        const onChangeFunction = jest.fn()
        const obj = shallow(
          <SearchBar onChangeTextInput={onChangeFunction} />
        )
        obj.find('TextInput').props().onChangeTextCallback('h')
        expect(onChangeFunction).toHaveBeenCalledWith('h')
      })

I getting a weird error stating :

TypeError: Cannot read property 'values' of undefined

  51 |           icon={this.icon}
  52 |           onChangeTextCallback={() => {
> 53 |             onChangeTextInput(this.searchForm.values)
     |                                                 ^
  54 |           }}
  55 |         />
  56 |         )

My obj.html() dump for the test looks like:

<Form name="searchForm" if={true}>
  <TextInput
    noSpacing={true}
    placeholder="search"
    name="search"
    validate="text"
    icon={{
      $$typeof: Symbol(react.element),
      type: [(Function: Icon)],
      key: null,
      ref: null,
      props: {
        name: "search",
        size: 25,
        color: "#00a8ca",
        style: { position: "absolute", right: 0, bottom: 7 },
        allowFontScaling: false,
        type: "MaterialIcons",
        if: true,
      },
      _owner: null,
      _store: {},
    }}
    onChangeTextCallback={[(Function: onChangeTextCallback)]}
    value={null}
    style={{}}
    hasFloatingLabel={true}
    numberOfLines={1}
    isPassword={false}
    if={true}
  />
  )
</Form>

what is happening here? I have custom form that gives me values through refs. Do I need to do something and maybe initialize the Form component? please help, I am relatively new to this stuff.

1 Answers

Issue

The ref callback isn't getting called so this.searchForm is undefined when onChangeTextCallback() is invoked.

Details

From the Callback Refs docs: "React will call the ref callback with the DOM element when the component mounts".

In the test you are using shallow(). Shallow rendering does not mount the component so the ref callback is never called.

Solution

Mount the component. Since you are already using Enzyme you can use mount(). Note that "full DOM rendering requires that a full DOM API be available at the global scope", for Jest you can configure the test environment to use jsdom.

Related