Mike
Mike

Reputation: 6239

Shallow render a React/Enzyme component that uses Refs

I have a React component that I'm testing with Enzyme, that for examples sake looks like this:

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

I am writing some unit tests using Mocha/Chai/Enzyme and I want to simulate the button press to check my props func gets called.

My basic Enzyme test looks like this:

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

Is there any way I can tweak the test or my component code to avoid an error when this.button is accessed in the click handler? I get "TypeError: Cannot read property 'classList' of undefined".

I want keep this as a shallow rendering unit test and don't want to deep render this component with mount, which would require the use of a browser-like env such as jsdom.

Thanks.

Upvotes: 3

Views: 4466

Answers (1)

1ven
1ven

Reputation: 7026

I think it's impossible.

Shallow rendering docs haven't documentation for ref property. But mount rendering docs have it.

Also, you can check this github issue.

In my opinion, to not use mount rendering, instead of accessing classList and nextElementSibling, set corresponding state variable and display needed classNames depending on this variable.

Upvotes: 3

Related Questions