Skip to content

Instantly share code, notes, and snippets.

@ushiboy
Created August 21, 2016 13:52
Show Gist options
  • Save ushiboy/fea4836fdda03e4d81e49c5a253f75d3 to your computer and use it in GitHub Desktop.
Save ushiboy/fea4836fdda03e4d81e49c5a253f75d3 to your computer and use it in GitHub Desktop.
React UnitTest Practice
{
"presets": [
"es2015",
"react"
],
"env": {
"development": {
"presets": [
"power-assert"
]
}
}
}
### https://raw.github.com/github/gitignore/ef8772f1346e95272f6ee2fa76ce502c88444a7b/Node.gitignore
# Logs
logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules
jspm_packages
# Optional npm cache directory
.npm
# Optional REPL history
.node_repl_history
import React, { Component } from 'react';
export class BeerListContainer extends Component {
constructor(props) {
super(props);
this.state = {
beers: []
}
this.addItem = this.addItem.bind(this);
}
render() {
return (
<div>
<InputArea onSubmit={this.addItem} />
<BeerList items={this.state.beers} />
</div>
);
}
addItem(name) {
this.setState({
beers: [].concat(this.state.beers).concat([name])
});
}
}
export class InputArea extends Component {
constructor(props) {
super(props);
this.state = {
text: ''
};
this.setText = this.setText.bind(this);
this.handleClick = this.handleClick.bind(this);
}
render() {
return (
<div>
<input value={this.state.text} onChange={this.setText} />
<button onClick={this.handleClick}>Add</button>
</div>
);
}
handleClick() {
this.props.onSubmit(this.state.text);
}
setText(event) {
this.setState({
text: event.target.value
});
}
}
InputArea.propTypes = {
onSubmit: React.PropTypes.func.isRequired
};
export class BeerList extends Component {
render() {
return this.props.items ? (
<ul>
{this.props.items.map((item, index) => (
<li key={index}>{item}</li>
))}
</ul>
) : null;
}
}
BeerList.propTypes = {
items: React.PropTypes.array.isRequired
};
const assert = require('assert');
import { spy } from 'sinon';
import React from 'react';
import { shallow, mount } from 'enzyme';
import { BeerListContainer, InputArea, BeerList } from './components';
describe('BeerListContainer', () => {
it('should render InputArea and BeerList', () => {
const wrapper = shallow(<BeerListContainer />);
assert.ok(wrapper.containsAllMatchingElements([
<InputArea />,
<BeerList />
]));
});
it('should start with an empty list', () => {
const wrapper = shallow(<BeerListContainer />);
const beers = wrapper.state('beers');
assert.ok(Array.isArray(beers));
assert(beers.length === 0);
});
it('adds items to the list', () => {
const wrapper = shallow(<BeerListContainer />);
wrapper.instance().addItem('Sam Adams');
assert(wrapper.state('beers')[0] === 'Sam Adams');
});
it('passes addItem to InputArea', () => {
const wrapper = shallow(<BeerListContainer />);
const inputArea = wrapper.find(InputArea);
const addItem = wrapper.instance().addItem;
assert(inputArea.prop('onSubmit') === addItem);
});
it('passes a bound addItem function to InputArea', () => {
const wrapper = shallow(<BeerListContainer />);
const inputArea = wrapper.find(InputArea);
inputArea.prop('onSubmit')('Sam Adams');
assert(wrapper.state('beers')[0] === 'Sam Adams');
});
});
describe('InputArea', () => {
it('should contain an input and a button', () => {
const wrapper = shallow(<InputArea />);
// assertのなかでcontainsAllMatchingElementsするとパースエラーになる
const result = wrapper.containsAllMatchingElements([
<input/>,
<button>Add</button>
]);
assert.ok(result);
});
it('should accept input', () => {
const wrapper = mount(<InputArea />);
const input = wrapper.find('input');
input.simulate('change', { target: { value: 'Resin' } });
assert(wrapper.state('text') === 'Resin');
assert(input.prop('value') === 'Resin');
});
it('should call onSubmit when Add is clicked', () => {
const addItemSpy = spy();
const wrapper = shallow(<InputArea onSubmit={addItemSpy} />);
wrapper.setState({ text: 'Octoberfest' });
const addButton = wrapper.find('button');
addButton.simulate('click');
assert.ok(addItemSpy.calledOnce);
assert.ok(addItemSpy.calledWith('Octoberfest'));
});
});
describe('BeerList', () => {
it('should render zero items', () => {
const wrapper = shallow(<BeerList items={[]} />);
assert(wrapper.find('li').length === 0);
});
it('should render undefined items', () => {
const wrapper = shallow(<BeerList items={undefined} />);
assert(wrapper.find('li').length === 0);
});
it('should render some items', () => {
const items = ['Sam Adams', 'Resin', 'Octoberfest'];
const wrapper = shallow(<BeerList items={items} />);
assert(wrapper.find('li').length === 3);
});
it('should render the items', () => {
const wrapper = mount(<BeerListContainer />);
wrapper.instance().addItem('Sam Adams');
wrapper.instance().addItem('Resin');
assert(wrapper.find('li').length === 2);
});
});
{
"name": "react-test",
"version": "0.1.0",
"description": "React Unit Test",
"main": "components.js",
"scripts": {
"test": "mocha --require setup.js *.spec.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-preset-es2015": "^6.13.2",
"babel-preset-power-assert": "^1.0.0",
"babel-preset-react": "^6.11.1",
"babel-register": "^6.11.6",
"enzyme": "^2.4.1",
"eslint": "^3.3.1",
"jsdom": "^9.4.2",
"mocha": "^3.0.2",
"power-assert": "^1.4.1",
"react": "^15.3.0",
"react-addons-test-utils": "^15.3.0",
"react-dom": "^15.3.0",
"sinon": "^1.17.5"
}
}
require('babel-register')();
var jsdom = require('jsdom').jsdom;
var exposedProperties = ['window', 'navigator', 'document'];
global.document = jsdom('');
global.window = document.defaultView;
Object.keys(document.defaultView).forEach((property) => {
if (typeof global[property] === 'undefined') {
exposedProperties.push(property);
global[property] = document.defaultView[property];
}
});
global.navigator = {
userAgent: 'node.js'
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment