I am trying to test that a child component exists by shallow-rendering it with Enzyme. However, it does not appear to be getting past the return of the component and instead shallow-renders <undefined />
.
import PropTypes from 'prop-types'
import React from 'react'
import createReactClass from 'create-react-class'
import ImmutablePropTypes from 'react-immutable-proptypes'
import MainComponent from './MainComponent'
import {addSelection} from '../../actions/betslip'
import {connect} from 'react-redux'
export const MainComponentContainter = createReactClass({
displayName: 'MainComponentCont',
propTypes: {
displayMode: PropTypes.string,
other: ImmutablePropTypes.map,
addSelection: PropTypes.func,
prices: ImmutablePropTypes.map,
selections: ImmutablePropTypes.map,
},
render() {
return (
<div>
{this.props.other.valueSeq().map(this.renderMain)}
</div>
)
},
renderMain(other) {
const yesOutcome = other.get('markets').first().get('outcomes').first()
const newPrice = this.props.prices.getIn([yesOutcome.get('id'), 'price'])
if (newPrice) {
return (
<MainComponent key={other.get('id')}
...some other props/>
)
}
return null
}
})
const mapStateToProps = () => {
return (state) => {
const displayMode = state.ui.get('displayMode')
const selections = state.stp.get('selections')
const prices = state.catalog.get('prices')
const other = state.catalog.get('other')
return {
displayMode,
other,
prices,
selections,
}
}
}
const mapDispatchToProps = {
addSelection,
}
export default connect(mapStateToProps, mapDispatchToProps)(MainComponentContainer)
This just basically returns another component to the above component.
return (
<div style={[styles.container, styles.container[displayMode]]}>
<div style={[styles.logo, styles.logo[displayMode]]}>
{renderLogo(displayMode, quoteExtraLogo)}
{displayMode === 'mobile' &&
renderButton({displayMode, selected, suspended, clickHandler})}
</div>
<div style={[styles.content, styles.content[displayMode]]}>
<h2 style={[styles.headline, styles.headline[displayMode]]}>
{title}
</h2>
<div style={[styles.offer, styles.offer[displayMode]]}>
<div style={[styles.details, styles.details[displayMode]]}>
<p style={[styles.market, styles.market[displayMode]]}>
{text}
</p>
<div>
<p style={[styles.improvedOdds, styles.improvedOdds[displayMode]]}>
<span style={styles.improvedOddsAt}>a</span> {newPrice}
</p>
<p style={[styles.previousOdds, styles.previousOdds[displayMode]]}>
invece di{' '}
<span className="strikethrough">
{oldPrice}
</span>
</p>
</div>
</div>
{displayMode === 'desktop' &&
renderButton({displayMode, selected, suspended, clickHandler})}
</div>
</div>
</div>
)
describe.only('MainComponentContainer Component', () => {
beforeEach(() => {
sandbox = sinon.sandbox.create()
addSelectionSpy = sinon.spy()
})
afterEach(() => {
sandbox.restore()
})
function getOutput({
displayMode = 'mobile',
other = mockData,
addSelection = spy,
prices = pricesMock,
selections = selectionsMock,
} = {}) {
return shallow(
<MainComponentContainer
displayMode = {displayMode}
other = {mockData}
addSelection = {addSelection}
prices = {prices}
selections = {selections}
/>
)
}
it('should include a MainComponent component', () => {
const pb = getOutput().find('MainComponent')
expect(pb.length).to.equal(1)
})
When doing the above test (should include a MainComponent
component), I get the following error:
AssertionError: expected 0 to equal 1 + expected - actual -0 +1
However I have logged out getOutput().debug()
, and it returns <div><undefined /></div>
.
The shallow
renderer is intentionally limited to operating on only the root component so as to make the test more isolated. In the case of decorators or "wrapped" components like this, the wrapped component is not what we want to test. Since MainComponentContainer
is a HOC, you face this problem.
There are two ways to get around this problem, either
First export the undecorated component
export default connect(mapStateToProps, mapDispatchToProps)(MainComponentContainer)
export {MainComponentContainer as ComponentContainer};
and test like
return shallow(
<ComponentContainer
displayMode = {displayMode}
other = {mockData}
addSelection = {addSelection}
prices = {prices}
selections = {selections}
/>
)
or use .dive
it('should include a MainComponent component', () => {
const pb = getOutput().dive().find('MainComponent')
expect(pb.length).to.equal(1)
})
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.