React

Tests

React

We break down our app into smaller pieces

Components

React

Tests may PASS or FAIL

React

Tests may PASS or FAIL

...but we also want to know what failed

React

Write useful tests

1. Find the bug

2. Reproduce it

3. Find the cause

4. Solve it!

React

Unit Tests with Jest


    describe("A suite", function() {
      it("contains spec with an expectation", function() {
        expect(true).toBe(true);
      });
    });

React

In real life we get an actual function

with Jest we get a mock of the function

BUT

Zoo.getAnimals()

React

Tests are mocked to

guarantee isolation

React

Zoo.getAnimals()

    jest.dontMock('Zoo');

    describe("Zoo.getAnimals()", function() {
      it("should contain more than 0 animals", function() {
        //...
      });
    });

React

    var getAnimals = function(callback){
        setTimeout(function(){
            callback(['monkey', 'bird', 'lion']);
        }, 0);
    }
    jest.dontMock('Zoo');

    describe("Zoo.getAnimals()", function() {
      it("should contain animals", function() {
        var Zoo = require('Zoo');

        let mockCallback = jest.genMockFunction();
        Zoo.getAnimals();
        
        jest.runAllTimers();
        expect(mockCallback)
           .toBeCalledWith(['monkey', 'bird', 'lion']);
      });
    });

React

Jest with React

React

React.addons.TestUtils

simple helpers for writing test cases

React

React.addons.TestUtils

Simulate

Simulate.{eventName}(DOMElement element, object eventData)

Examples

let node = React.findDOMNode(this.refs.input);

React.addons.TestUtils.Simulate.click(node);

React.addons.TestUtils.Simulate.change(node, 
                    {target: {value: 'Hello, world'}});

React.addons.TestUtils.Simulate.keyDown(node, {key: "Enter"});

React

React.addons.TestUtils

renderIntoDocument

ReactComponent renderIntoDocument(ReactElement instance)

Example

let label = <Label>label testing</Label>;
React.addons.TestUtils.renderIntoDocument(label);

React

React.addons.TestUtils

class PartyComponent extends React.Component {
    constructor(props) {
        super(props);

        this.state = {
            txt: this.props.children
        }
    }
    handleClick() {
        this.setState({
          txt: 'Lets have a party!'
        });
    }
    render() {
        return (<div>
          <p ref="party" onClick={this.handleClick.bind(this)}>{this.state.txt}</p>
      </div>);
    }
};

Example - PartyComponent

React

React.addons.TestUtils

jest.dontMock('../PartyComponent.jsx');
import * as addons from 'react/addons';

import React from 'react';
var PartyComponent = require('../PartyComponent.jsx');
let TestUtils = React.addons.TestUtils;

describe("PartyComponent Test", function(){
    let partyComponent, domNode;
    beforeEach(function() {
      let myComponent = <PartyComponent>No party at all</PartyComponent>;
      partyComponent = TestUtils.renderIntoDocument(myComponent);
      domNode = React.findDOMNode(partyComponent.refs.party);
    });

    it("Check Text Assignment", function () {
      expect(domNode).toBeDefined();
      expect(domNode.textContent).toBe("No party at all");
    });

    it("Click", function () {
      TestUtils.Simulate.click(partyComponent.refs.party);
      expect(domNode.textContent).toBe("Lets have a party!");
    });
});

Example 1 - PartyComponent

React

React.addons.TestUtils

Other relevant utils...

let vodoo = TestUtils.renderIntoDocument(<Vodoo />);

expect(TestUtils.findRenderedDOMComponentWithClass(vodoo,
 'fake').getDOMNode().innerHTML).toBe('Vodoo content!');
ReactComponent findRenderedDOMComponentWithClass(ReactComponent tree, string className)
let checkbox = TestUtils.renderIntoDocument(<Checkbox />);

let input = TestUtils.findRenderedDOMComponentWithTag(checkbox, 'input');
ReactComponent findRenderedDOMComponentWithTag(ReactComponent tree, string tagName)
import Button from "../Button";

let menu = TestUtils.renderIntoDocument(<Menu />);
let btn = TestUtils.findRenderedComponentWithType(menu, Button);
ReactComponent findRenderedComponentWithType(ReactComponent tree, function componentClass)

React

React.addons.TestUtils

Other relevant utils...

let vodoo = TestUtils.renderIntoDocument(<Vodoo />);
let array = TestUtils.scryRenderedDOMComponentsWithClass(vodoo, 'fake');
array scryRenderedDOMComponentsWithClass(ReactComponent tree, string className)
let checkbox = TestUtils.renderIntoDocument(<Checkbox />);
let array = TestUtils.scryRenderedDOMComponentsWithTag(checkbox, 'input');
array scryRenderedDOMComponentsWithTag(ReactComponent tree, string tagName)
import Button from "../Button";

let menu = TestUtils.renderIntoDocument(<Menu />);
let buttons = TestUtils.scryRenderedComponentsWithType(menu, Button);
array scryRenderedComponentsWithType(ReactComponent tree, function componentClass)

React

React.addons.TestUtils

Other relevant utils... conditionals!

boolean isElement(ReactElement element)
boolean isElementOfType(ReactElement element, function componentClass)
boolean isDOMComponent(ReactComponent instance)
boolean isCompositeComponent(ReactComponent instance)
boolean isCompositeComponentWithType(ReactComponent instance, function componentClass)

React

React.addons.TestUtils

Other relevant utils... 

array findAllInRenderedTree(ReactComponent tree, function test)
import Button from "../Button";

let menu = TestUtils.renderIntoDocument(<Menu />);

let menuComponents = TestUtils.findAllInRenderedTree(menu, function (elem) {
    return TestUtils.isCompositeComponentWithType(elem, Button);
});

expect(menuComponents.length).to.be(2);

React

React.addons.TestUtils

Other relevant utils... 

object mockComponent(function componentClass, string? mockTagName)

replaced by Shallow Rendering

React

React.addons.TestUtils

Shallow Rendering

ReactShallowRenderer createRenderer()
shallowRenderer.render(ReactElement element)
ReactComponent shallowRenderer.getRenderOutput()

React

React.addons.TestUtils

Shallow Rendering

ReactShallowRenderer createRenderer()
shallowRenderer.render(ReactElement element)
ReactComponent shallowRenderer.getRenderOutput()
<div>
  <span>React is awesome</span>
  <OtherComponent hello="world" />
</div>
let result = renderer.getRenderOutput();
expect(result.type).toBe('div');
expect(result.props.children).toEqual([
  <h1>React is awesome</h1>,
  <OtherComponent hello="world" />
]);

shallowRenderer.getRenderOutput()

Tests

React

"Jest is slow"

 

React

"Jest is slow"

 

JSX is slow

JSX        JS

React

JSX is slow

Possible solutions

- cache

- execute a JSX compiler on entire code base, save the results in a folder and run tests there 

React

Let's try this!

{ /* Tests */ }

 

1. Exercices

      #08-tests

 

REACT - Tests

By Daniela Matos de Carvalho

REACT - Tests

  • 1,596