Skip to content

Component testing

Camille Delbove edited this page Jan 30, 2018 · 16 revisions

Testing stack:

To test React components, we use the following stack:

Launch tests

bin/test assets/javacripts/kitten/components/{the_name}/{theName}.test.js

Configuration

The Mocha configuration is in /assets/javascrits/kitten/config/test-setup.js.

Write tests

We add the tests file in the same folder than the component. E.g.:

// assets/javascripts/kitten/components/buttons/button.js

import React, { Component } from 'react'
import classNames from 'classnames'

export class Button extends Component {
  render() {
    const {
      className,
      tag,
      modifier,
      size,
      icon,
      iconOnRight,
      iconWithMinWidth,
      ...others,
    } = this.props

    let buttonClassNames = classNames(
      'k-Button',
      {
        [`k-Button--${modifier}`]: modifier,
        [`k-Button--${size}`]: size,
        'k-Button--icon': icon,
        'k-Button--iconRight': iconOnRight,
        'k-Button--iconWithMinWidth': iconWithMinWidth,
        'k-Button--icon--tiny': size == 'tiny' && icon,
        'k-Button--iconRight--tiny': size == 'tiny' && iconOnRight,
      },
      className,
    )

    // Adds keyboard accessibility to `<a>`
    const tabindex = (tag == "a" && !this.props.href) ? 0 : null

    const Tag = tag

    return (
      <Tag
        className={ buttonClassNames }
        tabIndex={ tabindex }
        { ...others }
      />
    )
  }
}

Button.defaultProps = {
  tag: 'button',
  modifier: 'hydrogen',
  icon: false,
  iconOnRight: false,
  iconWithMinWidth: false,
}
// assets/javascripts/kitten/components/buttons/buttons.test.js

import React, { Component } from 'react'
import { Button } from 'kitten/components/buttons/button'

describe('Button with default props', () => {
  const component = shallow(<Button />)

  describe('by default', () => {
    it('is a <button>', () => {
      expect(component.type()).toBe('button')
    })

    it('has a k-Button class', () => {
      expect(component.hasClass('k-Button')).toBe(true)
    })

    it('has the hydrogen modifier class', () => {
      expect(component.hasClass('k-Button--hydrogen')).toBe(true)
    })

    it('does not have the iconRight modifier class', () => {
      expect(component.hasClass('k-Button--iconRight')).toBeFalsy()
    })

    it('does not have a tabindex attribute', () => {
      expect(component.props().tabindex).toBeFalsy()
    })
  })

  describe('className prop', () => {
    it('adds the class to the element', () => {
      const component = shallow(<Button className="meaow" />)
      expect(component.hasClass('meaow')).toBe(true)
    })
  })

  describe('modifier prop', () => {
    it('adds a class to the component', () => {
      const component = shallow(<Button modifier="helium" />)
      expect(component.hasClass('k-Button--helium')).toBe(true)
    })
  })

  describe('iconRight prop', () => {
    it('adds the iconRight modifier class', () => {
      const component = shallow(<Button iconOnRight />)
      expect(component.hasClass('k-Button--iconRight')).toBe(true)
    })
  })

  describe('tag prop', () => {
    it('changes the tag', () => {
      const component = shallow(<Button tag="a" />)
      expect(component.type()).toBe('a')
    })
  })

  describe('with tag="a" and no href', () => {
    it('adds a tabindex', () => {
      const component = shallow(<Button tag="a" />)
      expect(component.props().tabIndex).toBe(0)
    })
  })

  describe('with tag="a" href="foo"', () => {
    it('does not add a tabindex', () => {
      const component = shallow(<Button tag="a" href="foo" />)
      expect(component.props().tabIndex).toBeFalsy()
    })
  })
})

Clone this wiki locally