Thanks to visit codestin.com
Credit goes to www.slideshare.net

Front End Workshops
React Testing
Cristina Hernández García
chernandez@visual-engin.com
Mario García Martín
mgarcia@visual-engin.com
JavaScript Testing
Remember, remember...
Testing basics
Tools we’ll be using
describe("Use describe to group similar tests", function() {
});
Test framework Assertions library Test spies, stubs and mocks
*More info at http://mochajs.org/, http://chaijs.com/, and http://sinonjs.org/
describe
suite hooks
it
expect
beforeEach(function() {});
afterEach(function() {});
it("use it to test an attribute of a target", function() {
});
// use expect to make an assertion about a target
expect(foo).to.be.a('string');
expect(foo).to.equal('bar');
Test Driven Development (TDD)
The cycle of TDD
Benefits of TDD
Produces code that works
Honors the Single Responsibility Principle
Forces conscious development
Productivity boost
Run tests
Write a
test
Run tests
Make the
test pass
Refactor
Test Driven Development (TDD)
The cycle of TDD
Benefits of TDD
Produces code that works
Honors the Single Responsibility Principle
Forces conscious development
Productivity boost
Run tests
Write a
test
Run tests
Make the
test pass
Refactor
Testing React applications
What’s different?
React testing - Particularities (1 of 2)
Although not always required, sometimes it’s necessary to have a full DOM
API.
Components are rendered to a VDOM...
No need to fully render our components while testing!
global.document = jsdom.jsdom('<!doctype html><html><body></body></html>');
global.window = global.document.defaultView;
global.navigator = {
userAgent: 'node.js'
};
For console-based testing environments you can use the jsdom library to mock
the DOM document.
React testing - Particularities
Events simulation is needed
Components are rendered to a VDOM...
Higher level components can be tested in isolation. Shallow rendering.
View
ViewView
View View View View View
Lets you render a
component “one level
deep”.
You don’t have to worry
about the behavior of
child components.
React test utilities
Makes it easy to test React components in
the testing framework of your choice.
React test utilities (1 of 3) (react-addons-test-utils)
ReactComponent renderIntoDocument(ReactElement instance)
Render a component into a detached DOM node in the document.
Requires a full DOM API available at the global scope.
It does not require a DOM API.
ReactShallowRenderer
createRenderer()
shallowRenderer.render(ReactElement element)
ReactElement shallowRenderer.getRenderOutput()
Rendering components
Shallow rendering
React test utilities (2 of 3) (react-addons-test-utils)
Shallow rendering example
// MyComponent.js
import React, { Component } from
'react';
import Subcomponent from
'./Subcomponent';
class MyComponent extends Component {
render() {
return (
<div>
<span className="heading">
Title
</span>
<Subcomponent foo="bar" />
</div>
);
}
}
export default MyComponent;
// MyComponent.spec.js
import React from 'react';
import TestUtils from
'react-addons-test-utils';
import MyComponent from 'mycomponent';
const renderer =
TestUtils.createRenderer();
renderer.render(<MyComponent />);
const result =
renderer.getRenderOutput();
expect(result.type).to.equal('div');
expect(result.props.children).to.eql([
<span className="heading">Title</span>,
<Subcomponent foo="bar" />
]);
React test utilities (3 of 3) (react-addons-test-utils)
findAllInRenderedTree
scryRenderedDOMComponentsWithClass
findRenderedDOMComponentWithClass
scryRenderedDOMComponentsWithTag
findRenderedDOMComponentWithTag
scryRenderedDOMComponentsWithType
findRenderedDOMComponentWithType
Simulate an event dispatch on a DOM node with optional event data.
Simulate.{eventName}(DOMElement element, [object eventData])
Simulating React synthetic events
The rendered components interface...
Enzyme
JavaScript Testing utility for React.
Enzyme - Introduction
Now, with 150% neater interface!
.find(selector)
.findWhere(predicate)
.state([key])
.setState(nextState)
.prop([key])
.setProps(nextProps)
.parent()
.children()
.simulate(event[,
data])
.update()
.debug()
*The render function may not have all the methods advertised
Mimicks jQuery’s API DOM manipulation and traversal.
rendermountshallow
Enzyme - Shallow rendering
shallow(node[, options]) => ShallowWrapper
*More info at http://airbnb.io/enzyme/docs/api/shallow.html
const row = shallow(<TableRow columns={5} />)
// Using prop to retrieve the columns
property
expect(row.prop('columns')).to.eql(5);
// Using 'at' to retrieve the forth column's
content
expect(row.find(TableColumn).at(3).prop('content')).to.exist;
// Using first and text to retrieve the columns text
content
expect(row.find(TableColumn).first().text()).to.eql('First column');
// Simulating events
const button = shallow(<MyButton
/>);
button.simulate('click');
expect(button.state('myActionWasPerformed')).to.be.true;
Enzyme - Full DOM rendering
mount(node[, options]) => ReactWrapper
*More info at http://airbnb.io/enzyme/docs/api/mount.html
Use it when interacting with DOM or testing full lifecycle (componentDidMount).
it('calls componentDidMount', function() {
spy(Foo.prototype, 'componentDidMount');
const wrapper = mount(<Foo />);
expect(Foo.prototype.componentDidMount.calledOnce).to.equal(true);
});
it('allows us to set props', function() {
const wrapper = mount(<Foo bar='baz' />);
expect(wrapper.prop('bar')).to.equal('baz');
wrapper.setProps({ bar: 'foo' });
expect(wrapper.props('bar')).to.equal('foo');
});
Requires a full DOM API available at the global scope.
Enzyme - Static rendered markup
render(node[, options]) => CheerioWrapper
*More info at http://airbnb.io/enzyme/docs/api/render.html
Use it to render react components into static HTML (Uses Cheerio library).
it('renders three .foo-bar', function() {
const wrapper = render(<Foo />);
expect(wrapper.find('.foo-bar')).to.have.length(3);
});
it('rendered the title', function() {
const wrapper = render(<Foo title="unique" />);
expect(wrapper.text()).to.contain("unique");
});
Hands on code
Simpsons Wheel
Simpsons Wheel - General overview
App
generateRandInfo(<value>)
type: GENERATE_RANDINFO
payload: { value: 1, timestamp: 1234}
Reducers
STATE
randInfo: { value: 1, timestamp: 1234 }
Wheel
Button
Simpsons Wheel - Component details (1 of 2)
App component
Renders Wheel component, passing items prop
Renders Button component, passing max prop
Button component
Receives a max prop
When clicked, computes a random value between 1 and max
Calls action creator with the random number
Simpsons Wheel - Component details (2 of 2)
Wheel component
Renders the images
Stores the carousel
rotation in its state
Listens to Redux state
changes
Updates the rotation when
receives new props
Thanks for your time!
Do you have any questions?
Workshop 23: ReactJS, React & Redux testing

Workshop 23: ReactJS, React & Redux testing

  • 1.
    Front End Workshops ReactTesting Cristina Hernández García [email protected] Mario García Martín [email protected]
  • 2.
  • 3.
    Testing basics Tools we’llbe using describe("Use describe to group similar tests", function() { }); Test framework Assertions library Test spies, stubs and mocks *More info at http://mochajs.org/, http://chaijs.com/, and http://sinonjs.org/ describe suite hooks it expect beforeEach(function() {}); afterEach(function() {}); it("use it to test an attribute of a target", function() { }); // use expect to make an assertion about a target expect(foo).to.be.a('string'); expect(foo).to.equal('bar');
  • 4.
    Test Driven Development(TDD) The cycle of TDD Benefits of TDD Produces code that works Honors the Single Responsibility Principle Forces conscious development Productivity boost Run tests Write a test Run tests Make the test pass Refactor
  • 5.
    Test Driven Development(TDD) The cycle of TDD Benefits of TDD Produces code that works Honors the Single Responsibility Principle Forces conscious development Productivity boost Run tests Write a test Run tests Make the test pass Refactor
  • 6.
  • 7.
    React testing -Particularities (1 of 2) Although not always required, sometimes it’s necessary to have a full DOM API. Components are rendered to a VDOM... No need to fully render our components while testing! global.document = jsdom.jsdom('<!doctype html><html><body></body></html>'); global.window = global.document.defaultView; global.navigator = { userAgent: 'node.js' }; For console-based testing environments you can use the jsdom library to mock the DOM document.
  • 8.
    React testing -Particularities Events simulation is needed Components are rendered to a VDOM... Higher level components can be tested in isolation. Shallow rendering. View ViewView View View View View View Lets you render a component “one level deep”. You don’t have to worry about the behavior of child components.
  • 9.
    React test utilities Makesit easy to test React components in the testing framework of your choice.
  • 10.
    React test utilities(1 of 3) (react-addons-test-utils) ReactComponent renderIntoDocument(ReactElement instance) Render a component into a detached DOM node in the document. Requires a full DOM API available at the global scope. It does not require a DOM API. ReactShallowRenderer createRenderer() shallowRenderer.render(ReactElement element) ReactElement shallowRenderer.getRenderOutput() Rendering components Shallow rendering
  • 11.
    React test utilities(2 of 3) (react-addons-test-utils) Shallow rendering example // MyComponent.js import React, { Component } from 'react'; import Subcomponent from './Subcomponent'; class MyComponent extends Component { render() { return ( <div> <span className="heading"> Title </span> <Subcomponent foo="bar" /> </div> ); } } export default MyComponent; // MyComponent.spec.js import React from 'react'; import TestUtils from 'react-addons-test-utils'; import MyComponent from 'mycomponent'; const renderer = TestUtils.createRenderer(); renderer.render(<MyComponent />); const result = renderer.getRenderOutput(); expect(result.type).to.equal('div'); expect(result.props.children).to.eql([ <span className="heading">Title</span>, <Subcomponent foo="bar" /> ]);
  • 12.
    React test utilities(3 of 3) (react-addons-test-utils) findAllInRenderedTree scryRenderedDOMComponentsWithClass findRenderedDOMComponentWithClass scryRenderedDOMComponentsWithTag findRenderedDOMComponentWithTag scryRenderedDOMComponentsWithType findRenderedDOMComponentWithType Simulate an event dispatch on a DOM node with optional event data. Simulate.{eventName}(DOMElement element, [object eventData]) Simulating React synthetic events The rendered components interface...
  • 13.
  • 14.
    Enzyme - Introduction Now,with 150% neater interface! .find(selector) .findWhere(predicate) .state([key]) .setState(nextState) .prop([key]) .setProps(nextProps) .parent() .children() .simulate(event[, data]) .update() .debug() *The render function may not have all the methods advertised Mimicks jQuery’s API DOM manipulation and traversal. rendermountshallow
  • 15.
    Enzyme - Shallowrendering shallow(node[, options]) => ShallowWrapper *More info at http://airbnb.io/enzyme/docs/api/shallow.html const row = shallow(<TableRow columns={5} />) // Using prop to retrieve the columns property expect(row.prop('columns')).to.eql(5); // Using 'at' to retrieve the forth column's content expect(row.find(TableColumn).at(3).prop('content')).to.exist; // Using first and text to retrieve the columns text content expect(row.find(TableColumn).first().text()).to.eql('First column'); // Simulating events const button = shallow(<MyButton />); button.simulate('click'); expect(button.state('myActionWasPerformed')).to.be.true;
  • 16.
    Enzyme - FullDOM rendering mount(node[, options]) => ReactWrapper *More info at http://airbnb.io/enzyme/docs/api/mount.html Use it when interacting with DOM or testing full lifecycle (componentDidMount). it('calls componentDidMount', function() { spy(Foo.prototype, 'componentDidMount'); const wrapper = mount(<Foo />); expect(Foo.prototype.componentDidMount.calledOnce).to.equal(true); }); it('allows us to set props', function() { const wrapper = mount(<Foo bar='baz' />); expect(wrapper.prop('bar')).to.equal('baz'); wrapper.setProps({ bar: 'foo' }); expect(wrapper.props('bar')).to.equal('foo'); }); Requires a full DOM API available at the global scope.
  • 17.
    Enzyme - Staticrendered markup render(node[, options]) => CheerioWrapper *More info at http://airbnb.io/enzyme/docs/api/render.html Use it to render react components into static HTML (Uses Cheerio library). it('renders three .foo-bar', function() { const wrapper = render(<Foo />); expect(wrapper.find('.foo-bar')).to.have.length(3); }); it('rendered the title', function() { const wrapper = render(<Foo title="unique" />); expect(wrapper.text()).to.contain("unique"); });
  • 18.
  • 19.
    Simpsons Wheel -General overview App generateRandInfo(<value>) type: GENERATE_RANDINFO payload: { value: 1, timestamp: 1234} Reducers STATE randInfo: { value: 1, timestamp: 1234 } Wheel Button
  • 20.
    Simpsons Wheel -Component details (1 of 2) App component Renders Wheel component, passing items prop Renders Button component, passing max prop Button component Receives a max prop When clicked, computes a random value between 1 and max Calls action creator with the random number
  • 21.
    Simpsons Wheel -Component details (2 of 2) Wheel component Renders the images Stores the carousel rotation in its state Listens to Redux state changes Updates the rotation when receives new props
  • 22.
    Thanks for yourtime! Do you have any questions?