Joe Buza
Jest is a JavaScript testing framework, used by Facebook to test all JavaScript code including React applications.
// package.json
"dependencies": {
"react": "<current-version>",
"react-dom": "<current-version>"
},
"devDependencies": {
"babel-jest": "<current-version>",
"babel-preset-es2015": "<current-version>",
"babel-preset-react": "<current-version>",
"jest": "<current-version>",
"react-test-renderer": "<current-version>"
},
"scripts": {
"test": "jest"
}
// .babelrc
{
"presets": ["es2015", "react"]
}
// package.json
"devDependencies": {
"jest": "<current-version>"
},
"scripts": {
"test": "jest"
}
lets you automatically run the test suite on every file change.
"scripts": {
"watch:test": "jest --watch"
}
{
"scripts": {
"test": "jest --coverage"
},
"jest": {
"testEnvironment": "node",
"collectCoverageFrom": [
"src/*.js"
],
"coverageThreshold": {
"global": {
"branches": 100,
"functions": 50,
"lines": 33,
"statements": 25
}
}
}
}
{
"name": "testing-with-jest",
"version": "0.1.0",
"private": true,
"devDependencies": {
"enzyme": "^2.7.0",
"enzyme-to-json": "^1.4.5",
"react-addons-test-utils": "^15.4.2",
"react-dom": "^15.4.2",
"react-scripts": "0.8.5"
},
"dependencies": {
"react": "^15.4.2",
"react-dom": "^15.4.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"jest": {
"testEnvironment": "node",
"collectCoverageFrom": [
"src/*.js"
],
"coverageThreshold": {
"global": {
"branches": 100,
"functions": 50,
"lines": 33,
"statements": 25
}
}
}
}
Jest can capture snapshots of React trees or other serializable values to simplify UI testing.
JavaScript Testing utility for React that makes it easier to assert, manipulate, and traverse your React Components' output
import React, {Component, PropTypes} from 'react'
const STATUS = {
NORMAL:'normal',
HOVERED:'hovered'
}
class Link extends Component{
static propTypes = {
page: PropTypes.string,
style: PropTypes.object
}
state = {
class: STATUS.NORMAL
}
_handleMouseEnter = () => {
this.setState({class: STATUS.HOVERED})
}
_handleMouseLeave = () => {
this.setState({class: STATUS.NORMAL})
}
render(){
return (
<a
style={{...style, ...this.props.style}}
className={this.state.class}
href={this.props.page || '#'}
onMouseEnter={this._handleMouseEnter}
onMouseLeave={this._handleMouseLeave}
>
{this.props.children}
</a>
)
}
}
const style = {
textShadow: '2px 2px darkblue'
}
export default Link
import React from 'react'
// Third Party
import { shallow } from 'enzyme'
// Local
import Link from '../Link'
describe('<Link/>', ()=>{
let wrapper
beforeEach(()=>{
wrapper = shallow(
<Link page=""/>
)
})
it('should render', ()=>{
expect(wrapper).toBeDefined()
})
it('should have class normal by default', ()=>{
expect(wrapper.props().className).toBe('normal')
})
it('should have class hovered when mouse enters', ()=>{
wrapper.simulate('mouseEnter')
expect(wrapper.props().className).toBe('hovered')
})
it('should have class normal when mouse leaves', ()=>{
wrapper.props().onMouseEnter()
wrapper.props().onMouseLeave()
expect(wrapper.props().className).toBe('normal')
})
it('should have href of # when no page is passed in', ()=>{
expect(wrapper.props().href).toBe('#')
})
it('should have correct link when passed in', ()=>{
const page = "https://www.facebook.com"
wrapper.setProps({page})
expect(wrapper.props().href).toBe(page)
})
it('should pass children', ()=>{
const children = 'MY LINK'
wrapper.setProps({children})
expect(wrapper.text()).toMatch(children)
})
})
// Link.react-test.js
import React from 'react';
import Link from '../Link.react';
import renderer from 'react-test-renderer';
it('Link changes the class when hovered', () => {
const component = renderer.create(
<Link page="http://www.facebook.com">Facebook</Link>
);
let tree = component.toJSON();
expect(tree).toMatchSnapshot();
// manually trigger the callback
tree.props.onMouseEnter();
// re-rendering
tree = component.toJSON();
expect(tree).toMatchSnapshot();
// manually trigger the callback
tree.props.onMouseLeave();
// re-rendering
tree = component.toJSON();
expect(tree).toMatchSnapshot();
});
exports[`<Link/> snapshots Link changes the class when hovered 1`] = `
<a
className="normal"
href="http://www.facebook.com"
onMouseEnter={[Function]}
onMouseLeave={[Function]}
style={
Object {
"textShadow": "2px 2px darkblue",
}
}>
Facebook
</a>
`;
exports[`<Link/> snapshots Link changes the class when hovered 2`] = `
<a
className="hovered"
href="http://www.facebook.com"
onMouseEnter={[Function]}
onMouseLeave={[Function]}
style={
Object {
"textShadow": "2px 2px darkblue",
}
}>
Facebook
</a>
`;
exports[`<Link/> snapshots Link changes the class when hovered 3`] = `
<a
className="normal"
href="http://www.facebook.com"
onMouseEnter={[Function]}
onMouseLeave={[Function]}
style={
Object {
"textShadow": "2px 2px darkblue",
}
}>
Facebook
</a>
`;