Search code examples
reactjssinonchaienzymegrommet

Does Enzyme only work with lower level components?


I'm writing some unit tests for React/Redux/Grommet app. For testing I'm using Jest/Enzyme/Chai/Sinon.

I have the following component:

import React from 'react'
import FormField from 'grommet/components/FormField'
import Box from 'grommet/components/Box'
import Label from 'grommet/components/Label'
import TextInput from 'grommet/components/TextInput'

const CustomTextInput = ({label, value, onChange}) =>
    <FormField label={<Label size='small'>{label}</Label>}>
        <Box pad={{'horizontal': 'medium'}}>
            <TextInput placeholder='Please Enter' value={value}
                onDOMChange={event => onChange(event.target.value)}
            />
        </Box>
    </FormField>

export default CustomTextInput

And the following test fails :

import React from 'react';
import { shallow, mount, render } from 'enzyme';
import { expect } from 'chai'
var sinon = require('sinon');
import CustomTextInput from '../src/customInputs/CustomTextInput'
import TextInput from 'grommet/components/TextInput'
import Box from 'grommet/components/Box'
import FormField from 'grommet/components/FormField'


describe('<CustomTextInput />', () => {
    it('input changes', () => {
        let onChange = sinon.spy();
        const wrapper = shallow(<CustomTextInput label={'test'} value={'test'} onChange={onChange} />)
        wrapper.find(TextInput).simulate('keypress', {which: 'a'})
        expect(onChange.called).to.equal(true)
    })
})

With this error:

AssertionError: expected false to equal true

I've tried to simulate the onChange function a couple of different ways, mainly taking ideas from here and here. i.e.

wrapper.find(TextInput).value = 'test'
wrapper.find(TextInput).simulate('change', {target: {value: 'test'}})
wrapper.find(TextInput).first().simulate('change', {target: {value: 'test'}})

I'm starting to wonder if the simulate method of enzyme has trouble interacting with higher level library components like the ones from grommet or if it needs to be applied directed to a lower-level <input> tag. Has anyone experienced this sort of thing?


Solution

  • grommet TextInput is just a wrapper on standard input form field, so try this:

    wrapper.find('input').simulate('change', {target: { value: 'a'}});
    

    I hope my answer can be helpful for you!