Skip to content

Instantly share code, notes, and snippets.

@luishrd
Last active June 27, 2018 16:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save luishrd/37de05b90faef04b9307ac116489e333 to your computer and use it in GitHub Desktop.
Save luishrd/37de05b90faef04b9307ac116489e333 to your computer and use it in GitHub Desktop.
React Testing
// /.gitignore
# See https://help.github.com/ignore-files/ for more about ignoring files.
# dependencies
/node_modules
# testing
/coverage
# production
/build
# editor
.vscode
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*
// src/components/App.js
import React, { Component } from 'react';
import Display from './Display';
class App extends Component {
state = {
isLocked: true,
isOpen: false,
};
toggleLocked = () => {
this.setState(prevState => ({ isLocked: !prevState.isLocked }));
alert('lock button clicked!');
};
render() {
return (
<div className="app">
<div>
<button onClick={this.toggleLocked} className="lock-btn">
Lock
</button>
</div>
<Display isLocked={this.state.isLocked} isOpen={this.state.isOpen} />
</div>
);
}
}
export default App;
// src/components/App.spec.js
import React from 'react';
import { shallow } from 'enzyme';
import App from './App';
describe('App component', () => {
// challenge: DRY the tests using beforeEach to instantiate the component
it('should set isLocked to true when component mounts', () => {
const expected = true;
const component = shallow(<App />);
const instance = component.instance();
expect(instance.state.isLocked).toEqual(expected);
});
// challenge: check that isOpen starts false
it('should toggle isLocked when toggleLocked is called', () => {
const component = shallow(<App />);
const instance = component.instance();
let isLocked = instance.state.isLocked;
instance.toggleLocked();
expect(instance.state.isLocked).toEqual(false);
instance.toggleLocked();
expect(instance.state.isLocked).toEqual(true);
instance.toggleLocked();
expect(instance.state.isLocked).toEqual(false);
});
// challenge: write a test and implementation for toggling isOpen the BDD way
it('should show the correct message when clicking the Lock button', () => {
// mock the alert function
window.alert = jest.fn();
const component = shallow(<App />);
const instance = component.instance();
let isLocked = instance.state.isLocked;
const button = component.find('.lock-btn');
button.simulate('click');
expect(window.alert).toHaveBeenCalledWith('lock button clicked!');
expect(window.alert).toHaveBeenCalledTimes(1);
});
});
// src/components/Display.js
import React from 'react';
import { bool } from 'prop-types';
function Display(props) {
return (
<div className="display">
<h1>Display</h1>
<div>{props.isLocked ? 'Locked' : 'Unlocked'}</div>
<div>{props.isOpen ? 'Open' : 'Closed'}</div>
</div>
);
}
Display.propTypes = {
isLocked: bool.isRequired,
isOpen: bool.isRequired,
};
export default Display;
// src/components/Display.spec.js
import React from 'react';
import { shallow } from 'enzyme';
import Display from './Display';
describe.skip('Display component', () => {
it('should not differ from snapshot', () => {
let props = { isLocked: true, isOpen: false };
let element = shallow(<Display {...props} />);
expect(element).toMatchSnapshot();
props = { isLocked: true, isOpen: true };
element = shallow(<Display {...props} />);
expect(element).toMatchSnapshot();
props = { isLocked: false, isOpen: true };
element = shallow(<Display {...props} />);
expect(element).toMatchSnapshot();
props = { isLocked: false, isOpen: false };
element = shallow(<Display {...props} />);
expect(element).toMatchSnapshot();
});
});
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './components/App';
ReactDOM.render(<App />, document.getElementById('root'));
// src/index.spec.js
import App from './components/App';
describe.skip('index.js', () => {
it('renders App component', () => {});
});
{
"name": "testingreact",
"version": "1.0.0",
"private": true,
"dependencies": {
"enzyme": "^3.3.0",
"enzyme-adapter-react-16": "^1.1.1",
"react": "^16.3.2",
"react-dom": "^16.3.2",
"react-scripts": "^1.1.4",
"react-test-render": "^1.1.1"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test --env=jsdom",
"eject": "react-scripts eject"
},
"devDependencies": {
"prop-types": "^15.6.1"
}
}
// src/setupTests.js
import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
configure({ adapter: new Adapter() });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment