Last active
December 20, 2017 13:37
-
-
Save busypeoples/d9b878f0ba74786651e4 to your computer and use it in GitHub Desktop.
Testing in React: Basic Examples + Setup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "example-karma-jasmine-webapck-test-setup", | |
"description": "React Test Setup with Karma/Jasmine/Webpack", | |
"scripts": { | |
"test": "karma start --single-run --browsers PhantomJS" | |
}, | |
"devDependencies": { | |
"babel": "^6.5.2", | |
"babel-core": "^6.5.2", | |
"babel-eslint": "^5.0.0", | |
"babel-loader": "^6.2.3", | |
"babel-preset-airbnb": "^1.1.1", | |
"babel-preset-es2015": "^6.5.0", | |
"babel-preset-react": "^6.5.0", | |
"enzyme": "^2.0.0", | |
"jasmine-core": "^2.4.1", | |
"json-loader": "^0.5.4", | |
"karma": "^0.13.21", | |
"karma-babel-preprocessor": "^6.0.1", | |
"karma-jasmine": "^0.3.7", | |
"karma-phantomjs-launcher": "^1.0.0", | |
"karma-sourcemap-loader": "^0.3.7", | |
"karma-webpack": "^1.7.0", | |
"lodash": "^4.5.1", | |
"phantomjs-prebuilt": "^2.1.4", | |
"react": "^0.14.7", | |
"react-addons-test-utils": "^0.14.7", | |
"react-dom": "^0.14.7", | |
"react-test-utils": "0.0.1", | |
"webpack": "^1.12.14" | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"name": "example-mocha-jsdom-test-setup", | |
"description": "React Test Setup with Mocha/jsdom", | |
"scripts": { | |
"test": "mocha --require ./setup.js --compilers js:babel-core/register --recursive" | |
}, | |
"devDependencies": { | |
"babel": "^6.5.2", | |
"babel-core": "^6.6.5", | |
"babel-loader": "^6.2.4", | |
"enzyme": "^2.0.0", | |
"expect": "^1.14.0", | |
"jsdom": "^8.1.0", | |
"mocha": "^2.4.5", | |
"react-addons-test-utils": "^0.14.7" | |
}, | |
"dependencies": { | |
"react": "^0.14.7", | |
"react-dom": "^0.14.7" | |
} | |
} | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react' | |
const Release = React.createClass({ | |
render() { | |
const { title, artist, outOfPrint } = this.props.release; | |
const className = outOfPrint? 'release outOfPrint' : 'release'; | |
return ( | |
<tr className={className} > | |
<td className="artist">{ artist }</td> | |
<td className="title">{ title }</td> | |
<td className="comment">{ outOfPrint ? <span style={{color: 'red', fontStyle: 'italic'}}>Out Of Print!</span> : null }</td> | |
</tr> | |
); | |
} | |
}); | |
const ReleaseTable = React.createClass({ | |
render() { | |
const { searchText, releases, noOutOfPrint } = this.props; | |
const rows = releases.filter((release) => { | |
return (release.title.indexOf(searchText) !== -1 | |
|| release.artist.indexOf(searchText) !== -1) | |
&& !(release.outOfPrint && noOutOfPrint); | |
}); | |
return ( | |
<table className="releaseTable"> | |
<thead> | |
<tr> | |
<th>Artist</th> | |
<th>Title</th> | |
<th>Comment</th> | |
</tr> | |
</thead> | |
<tbody>{rows.map(release => { | |
return <Release release={ release } | |
key={ release.title } /> | |
})}</tbody> | |
</table> | |
); | |
} | |
}); | |
const SearchBar = React.createClass({ | |
updateSearch() { | |
this.props.onSearch( | |
this.refs.search.value, | |
this.refs.noOutOfPrint.checked | |
); | |
}, | |
render() { | |
return ( | |
<form className="searchBar"> | |
<input | |
type="text" | |
placeholder="Search..." | |
value={this.props.searchText} | |
ref="search" | |
onChange={this.updateSearch} | |
id="searchFilter" | |
/> | |
<p> | |
<input | |
type="checkbox" | |
checked={this.props.noOutOfPrint} | |
ref="noOutOfPrint" | |
onChange={this.updateSearch} | |
id="noOutOfPrint" | |
/> | |
{' '} | |
Only show available releases | |
</p> | |
</form> | |
); | |
} | |
}); | |
const Root = React.createClass({ | |
getInitialState() { | |
return { | |
searchText: '', | |
noOutOfPrint: false | |
}; | |
}, | |
updateSearch: function (searchText, noOutOfPrint) { | |
this.setState({ searchText, noOutOfPrint }); | |
}, | |
render() { | |
return ( | |
<div className="main"> | |
<SearchBar | |
searchText={this.state.searchText} | |
inStockOnly={this.state.noOutOfPrint} | |
onSearch={this.updateSearch} | |
/> | |
<ReleaseTable | |
releases={this.props.releases} | |
searchText={this.state.searchText} | |
noOutOfPrint={this.state.noOutOfPrint} | |
/> | |
</div> | |
); | |
} | |
}); | |
export { | |
Release, | |
ReleaseTable, | |
SearchBar | |
}; | |
export default Root; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react' | |
import { shallow, mount, render } from 'enzyme' | |
import Root, { SearchBar, ReleaseTable, Release } from '../src/Root' | |
const createShallowRelease = (outOfPrint = true) => { | |
let props = {release: { artist: 'foobar', title: 'bar', outOfPrint }}; | |
return shallow(<Release {...props} />); | |
}; | |
const createShallowRelaseTable = (noOutOfPrint = false, searchText = '') => { | |
let items = [{ artist: 'foobar', title: 'bar', outOfPrint: true }]; | |
let props = { searchText, releases: items, noOutOfPrint }; | |
return shallow(<ReleaseTable { ...props } />); | |
} | |
describe('<SearchBar>', () => { | |
let onSearch; | |
beforeEach(() => { | |
onSearch = jasmine.createSpy('onSearch'); | |
}); | |
it('calls onSearch when search text changes', () => { | |
let props = { searchText: '', noOutOfPrint: false, onSearch }; | |
let search = mount(<SearchBar { ...props } />); | |
let input = search.find('#searchFilter'); | |
input.get(0).value = 'foobar'; | |
input.simulate('change'); | |
expect(onSearch).toHaveBeenCalledWith('foobar', false); | |
}); | |
it('calls onSearch when no out print is checked', () => { | |
let props = { searchText: '', noOutOfPrint: false, onSearch }; | |
let search = mount(<SearchBar { ...props } />); | |
let input = search.find('#noOutOfPrint'); | |
input.get(0).checked = true; | |
input.simulate('change', {target: { checked: true }}); | |
expect(onSearch).toHaveBeenCalledWith('', true); | |
}); | |
}); | |
describe('<ReleaseTable>', () => { | |
it('contains the class name releaseTable', () => { | |
let release = createShallowRelaseTable(); | |
expect(release.is('.releaseTable')).toBeTruthy(); | |
}); | |
it('renders release item', () => { | |
let release = createShallowRelaseTable(); | |
expect(release.find(Release).length).toBe(1); | |
}); | |
it('filters out any out of print items', () => { | |
let release = createShallowRelaseTable(true, ''); | |
expect(release.find(Release).length).toBe(0); | |
}); | |
it('filters out any out of items when filtering by search text', () => { | |
let release = createShallowRelaseTable(false, 'bla'); | |
expect(release.find(Release).length).toBe(0); | |
}); | |
}); | |
describe('<Release>', () => { | |
it('contains the class name release', () => { | |
let release = createShallowRelease(); | |
expect(release.is('.release')).toBeTruthy(); | |
}); | |
it ('contains the class name outOfPrint if out of print', () => { | |
let release = createShallowRelease(true); | |
expect(release.is('.outOfPrint')).toBeTruthy(); | |
}); | |
it ('does not contain the class name outOfPrint if available', () => { | |
let release = createShallowRelease(false); | |
expect(release.is('.outOfPrint')).toBeFalsy(); | |
}); | |
it ('renders the artist name', () => { | |
let release = createShallowRelease(); | |
expect(release.find('.artist').text()).toEqual('foobar'); | |
}); | |
it ('renders the release title', () => { | |
let release = createShallowRelease(); | |
expect(release.find('.title').text()).toEqual('bar'); | |
}); | |
it ('renders the correct comment', () => { | |
let release = createShallowRelease(true); | |
expect(release.find('.comment').text()).toEqual('Out Of Print!'); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// needed when choosing the mocha/jsdom setup | |
var jsdom = require('jsdom') | |
global.document = jsdom.jsdom('<!doctype html><html><body></body></html>') | |
global.window = document.defaultView; | |
global.navigator = {userAgent: 'node.js'}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment