Неглубокий рендеринг компонента React / Enzyme, который использует ссылки

У меня есть компонент React, который я тестирую с помощью Enzyme, который для примера выглядит так:

import React, {Component} from 'react'

class Foo extends Component {
  constructor(props) {
    super(props)
    this.showContents = this.showContents.bind(this)
  }

  showContents() {
    this.button.classList.toggle("active")
    this.button.nextElementSibling.classList.toggle("show")
    this.props.onRequestShowContents()
  }

  render() {
    return (
      <div className="wrapper">
        <button ref={(ref) => this.button = ref} onClick={this.showContents}>Click to view contents</button>
        <div className="panel">
          {this.props.contents}
        </div>
      </div>
    )
  }
}

export default Foo

Я пишу несколько модульных тестов с использованием Mocha / Chai / Enzyme, и я хочу имитировать нажатие кнопки, чтобы проверить, вызывается моя функция props.

Мой базовый ферментный тест выглядит так:

import React from 'react'
import { shallow } from 'enzyme'
import Foo from '../components/Foo'
import chai from 'chai'
import expect from 'expect'
var should = chai.should()

function setup() {
  const props = {
    onRequestShowContents: expect.createSpy(),
    contents: null
  }

  const wrapper = shallow(<Foo {...props} />)

  return {
    props,
    wrapper
  }
}

describe('components', () => {
  describe('Foo', () => {
    it('should request contents on button click', () => {
      const { props, wrapper } = setup()
      const button = wrapper.find('button')
      button.props().onClick() //this line causes the error
      props.onRequestShowContents.calls.length.should.equal(1)
    })
  })
})

Есть ли способ настроить тест или код моего компонента, чтобы избежать ошибки при обращении к this.button в обработчике кликов? Я получаю «TypeError: невозможно прочитать свойство classList из undefined».

Я хочу сохранить это как неглубокий модульный тест рендеринга и не хочу выполнять глубокий рендеринг этого компонента с помощью mount, что потребовало бы использования браузерного env, такого как jsdom.

Спасибо.


person Mike    schedule 11.08.2016    source источник


Ответы (1)


Я думаю, что это невозможно.

Мелкая визуализация docs не содержит документации по свойству ref. Но при монтировании рендеринга docs он есть.

Также вы можете проверить эту проблему с github.

На мой взгляд, чтобы не использовать рендеринг монтирования, вместо доступа к classList и nextElementSibling установите соответствующую переменную состояния и отобразите необходимые имена классов в зависимости от этой переменной.

person 1ven    schedule 11.08.2016
comment
Хорошее предложение. Я использую Redux для управления состоянием, поэтому я, вероятно, смог бы построить правильный список классов в моем компоненте response-redux connect() более высокого порядка. Я хочу поблагодарить вас за это. - person Mike; 11.08.2016
comment
@Michael, я думаю, для этой цели у вас может быть локальное состояние, даже если вы используете redux. Бывший. this.state = { isVisible = false }, затем, когда вы щелкнете button, переключите эту переменную состояния и в функции render в зависимости от этой переменной отобразите соответствующий класс. - person 1ven; 11.08.2016
comment
Я хотел бы сохранить этот компонент представления без сохранения состояния, поэтому я могу передать опору show, управляемую сверху, а затем отобразить правильный класс (классы) в результате внутри компонента на основе this.props.show. - person Mike; 11.08.2016