【问题标题】:Enzyme not shallow rendering child酵素不浅渲染子
【发布时间】:2018-03-14 17:09:46
【问题描述】:

我正在尝试通过使用 Enzyme 对其进行浅层渲染来测试子组件是否存在。但是,它似乎没有超过组件的返回,而是浅渲染<undefined />。

MainComponentContainer.js

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)

MainComponent.js

这基本上只是将另一个组件返回到上述组件。

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)
  })

在进行上述测试时(应包含MainComponent 组件),我收到以下错误:

 AssertionError: expected 0 to equal 1
 + expected - actual

 -0
 +1

但是我已经注销getOutput().debug(),它返回&lt;div&gt;&lt;undefined /&gt;&lt;/div&gt;。

【问题讨论】:

  • 你能做一个不那么冗长的例子来重现问题吗?

标签: reactjs chai enzyme


【解决方案1】:

shallow 渲染器有意限制为仅对根组件进行操作,以使测试更加隔离。在像这样的装饰器或“包装”组件的情况下,被包装的组件不是我们想要测试的。由于MainComponentContainer 是一个 HOC,所以你面临这个问题。

有两种方法可以解决这个问题,要么

先导出未修饰的组件

export default connect(mapStateToProps, mapDispatchToProps)(MainComponentContainer)
export {MainComponentContainer as ComponentContainer};

然后像这样测试

return shallow(
  <ComponentContainer
    displayMode = {displayMode}
    other = {mockData}
    addSelection = {addSelection}
    prices = {prices}
    selections = {selections}
  />
)

或使用.dive

  it('should include a MainComponent component', () => {
    const pb = getOutput().dive().find('MainComponent')
    expect(pb.length).to.equal(1)
  })

【讨论】:

  • 好的,但这不会导致&lt;MainComponentContainer&gt;上的子组件不是&lt;undefined /&gt;吗?
  • 这两种方法你都试过了吗?
  • 我会尝试,但我只是寻求一点解释。是否有必要将MainComponentContainer 导出为ComponentContainer 与export const MainComponentContainer 有什么不同?
  • 不,没有什么不同,您可以使用 export const MainComponentContainer 。唯一的问题是您需要导出未连接的容器
  • 好的,我已经这样做了,但是为什么该组件上的shallow 会导致呈现&lt;undefined /&gt; 子级?因此,当我通过执行console.log(getOutput().debug()) 注销组件时,它会变浅&lt;div&gt;&lt;undefined /&gt;&lt;/div&gt;
猜你喜欢
  • 2018-06-16
  • 1970-01-01
  • 2018-09-25
  • 1970-01-01
  • 2016-10-29
  • 2019-03-19
  • 2019-06-11
  • 2020-03-12
  • 2019-03-14
相关资源
最近更新 更多