Daniel Kaczmarek Daniel Kaczmarek - 3 years ago 135
React JSX Question

Failing case during testing react component

I've got problem with testing react component. Here's my code.

// Component textfield-input.jsx
import React, { PropTypes } from 'react'
import HelpComponent from '../../atoms/help-component'

export default function TextField(props) {
const { helpMessage, label, error, ...rest } = props
return (
<div className="text-field">
<label htmlFor={props.name} className="name-label">
{label}
{helpMessage ?
<HelpComponent message={helpMessage} /> : null
}
</label>
{props.required ? <span className="dot">*</span> : null}
<input className={`input ${error ? 'error' : ''}`} {...rest} />
{error && (<span className="error-text">{error}</span>)}
</div>
)
}

TextField.propTypes = {
name: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
helpMessage: PropTypes.string,
error: PropTypes.string,
required: PropTypes.bool,
}


This is my TextField component.

// Help Component
import React, { PropTypes } from 'react'

export default function HelpComponent(props) {
const direction = props.direction || 'right'

return (
<i
className="fa fa-question-circle"
data-toggle="tooltip"
data-placement={direction}
title={props.message}
aria-hidden="true"
/>
)
}

HelpComponent.propTypes = {
direction: PropTypes.string,
message: PropTypes.string.isRequired
}


This is my HelpComponent that is used in TextField component.

// Test textfield-input.spec.jsx
import React from 'react'
import { shallow } from 'enzyme'

import TextField from '../../src/components/molecules/form/textfield-input'

describe('Unit: TextField component', () => {
let component
let props = {
name: 'text',
label: 'Text',
}
const COMPONENT = <TextField {...props} />

beforeEach(() => {
component = shallow(COMPONENT)
})

it('should be react component', () => {
expect(component.exists()).to.be.true
})

it('should render proper TextField', () => {
expect(component.find('.text-field').exists()).to.be.true
expect(component.find('.name-label').contains(props.label)).to.be.true
expect(component.find(`input[name="${props.name}"]`).exists()).to.be.true
})

it('should render help message', () => {
component.setProps({ helpMessage: 'help message' })
expect(component.find('.fa').exists()).to.be.true
})
})


Test spec. Should test TextField input. But 'should render help message' case is failing. Any other case works.

AssertionError: expected false to be true. But it should be true.

Edit: It's even worse after switching form shallow to mount. All cases fails then - exception for 'should be react component' - pass.

Solution: @shota is right. I should use mount instead of shallow. But my test cases were also wrong. This is the right way.

expect(component.find('.name-label').text()).to.equal(props.label)


instead of

expect(component.find('.name-label').contains(props.label)).to.be.true


Now everything works fine.

Thx~!

Answer Source

You are using shallow rendering, that is why it is failing. When using shallow rendering the child components won't be rendered but will stay as components.

So in your case, it won't go down into the child component and test whether the class exists there, but test immediate nodes in render method and raw components without rendering them.

So if you need to test child components too, you need full dom rendering

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download