Skip to content

Instantly share code, notes, and snippets.

@vjwilson
Created September 20, 2017 00:34
Show Gist options
  • Save vjwilson/d3d24c99488122fd262d46d7e3b6b00a to your computer and use it in GitHub Desktop.
Save vjwilson/d3d24c99488122fd262d46d7e3b6b00a to your computer and use it in GitHub Desktop.
Redux testing
# add Redux-specific files and tests
# Actions
touch src/actions/actionTypes.js
touch src/actions/linkActions.test.js
touch src/actions/linkActions.js
# Reducers
touch src/reducers/index.js
touch src/reducers/linkReducer.test.js
touch src/reducers/linkReducer.js
# Initial state
touch src/reducers/initialState.test.js
touch src/reducers/initialState.js
# create a store
touch src/store/configureStore.js
# edit App component and index.js
export const INCREMENT_FAVORITE_COUNT = 'INCREMENT_FAVORITE_COUNT';
@@ -1,38 +1,14 @@
import React, { Component } from 'react';
+import { connect } from 'react-redux';
import logo from '../../logo.svg';
import LinkList from '../LinkList/LinkList';
-import './App.css';
-
-class App extends Component {
- constructor(props) {
- super(props);
-
- this.state = {
- links: props.links
- };
-
- this.incrementLinkCount = this.incrementLinkCount.bind(this);
- }
-
- incrementLinkCount(linkUrl) {
- const updatedLinkList = this.state.links.map((link) => {
- if (link.linkUrl === linkUrl) {
- return {
- linkUrl: link.linkUrl,
- favorites: link.favorites + 1
- };
- } else {
- return link;
- }
- });
+import { incrementFavorites } from '../../actions/linkActions.js';
- this.setState({
- links: updatedLinkList
- });
- }
+import './App.css';
+export class App extends Component {
render() {
return (
<div className="app">
@@ -41,16 +17,28 @@ class App extends Component {
<h1>Welcome to Linkshare</h1>
</header>
<main className="app-intro">
- <LinkList links={this.state.links} increment={this.incrementLinkCount} />
+ <LinkList links={this.props.links} increment={this.props.incrementLinkCount} />
</main>
<footer className="app-footer">
<span className="attribution">
- Icon made by <a href="http://www.freepik.com/" target="_blank">Freepik</a> from <a href="www.flaticon.com" target="_blank">www.flaticon.com</a>
+ Icon made by <a href="http://www.freepik.com/" target="_blank" rel="noopener noreferrer">Freepik</a> from <a href="www.flaticon.com" target="_blank" rel="noopener noreferrer">www.flaticon.com</a>
</span>
</footer>
</div>
);
}
}
-export default App;
+function mapStateToProps(state) {
+ return {
+ links: state.links
+ };
+}
+
+function mapDispatchToProps(dispatch) {
+ return {
+ incrementLinkCount: (linkUrl) => dispatch(incrementFavorites(linkUrl))
+ };
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(App)
@@ -1,7 +1,7 @@
import React from 'react';
import { shallow, mount } from 'enzyme';
-import App from './App';
+import { App } from './App';
import LinkItem from '../LinkItem/LinkItem';
describe('App component', () => {
@@ -33,30 +33,4 @@ describe('App component', () => {
expect(header).toHaveClassName('app-footer');
});
-
- it('should increment the specified favorite count', () => {
- const links = [
- {
- linkUrl: 'http://www.csszengarden.com',
- favorites: 10
- },
- {
- linkUrl: 'https://daringfireball.net',
- favorites: 15
- }
- ];
- const linkToTest = 1;
- const secondLinkCount = links[linkToTest].favorites;
- const props = {
- links: links
- };
- const wrapper = mount(<App {...props} />);
-
- const secondAddButton = wrapper.find(LinkItem).at(linkToTest);
- secondAddButton.find('.add-fave').simulate('click');
-
- const updatedLinks = wrapper.state('links');
- const secondLinkInState = updatedLinks[linkToTest];
- expect(secondLinkInState.favorites).toEqual(secondLinkCount + 1);
- });
});
import {createStore} from 'redux';
import rootReducer from '../reducers';
export default function configureStore(initialState) {
return createStore(
rootReducer,
initialState,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
}
import { combineReducers } from 'redux';
import links from './linkReducer';
const rootReducer = combineReducers({
links
});
export default rootReducer;
@@ -1,28 +1,17 @@
import React from 'react';
import ReactDOM from 'react-dom';
+import { Provider } from 'react-redux';
import './index.css';
+
import App from './components/App/App';
import registerServiceWorker from './registerServiceWorker';
+import configureStore from './store/configureStore';
-const links = [
- {
- linkUrl: 'http://www.csszengarden.com',
- favorites: 10
- },
- {
- linkUrl: 'https://daringfireball.net',
- favorites: 15
- },
- {
- linkUrl: 'https://alistapart.com',
- favorites: 9
- },
- {
- linkUrl: 'https://www.smashingmagazine.com',
- favorites: 18
- }
-];
-
+const store = configureStore();
-ReactDOM.render(<App links={links} />, document.getElementById('root'));
+ReactDOM.render(
+ <Provider store={store}>
+ <App />
+ </Provider>,
+ document.getElementById('root'));
registerServiceWorker();
export default {
links: [
{
linkUrl: 'http://www.csszengarden.com',
favorites: 10
},
{
linkUrl: 'https://daringfireball.net',
favorites: 15
},
{
linkUrl: 'https://alistapart.com',
favorites: 9
},
{
linkUrl: 'https://www.smashingmagazine.com',
favorites: 18
}
]
};
import initialState from './initialState';
describe('initialState constants', () => {
it('should supply an array of 4 links', () => {
expect(initialState.links).toHaveLength(4);
});
});
import * as types from './actionTypes';
export function incrementFavorites(linkUrl) {
return { type: types.INCREMENT_FAVORITE_COUNT, linkUrl };
}
import * as linkActions from '../actions/linkActions';
import * as types from './actionTypes';
describe('Favorite actions', () => {
it('increments the favorite count by one', () => {
const linkUrl = 'http://www.csszengarden.com';
const expectedAction = {
type: types.INCREMENT_FAVORITE_COUNT,
linkUrl: linkUrl
};
const action = linkActions.incrementFavorites(linkUrl);
expect(action).toEqual(expectedAction);
});
});
import * as types from '../actions/actionTypes';
import initialState from './initialState';
export default function linkReducer(state = initialState.links, action) {
if (action.type === types.INCREMENT_FAVORITE_COUNT) {
return state.map((link) => {
if (link.linkUrl === action.linkUrl) {
return {
linkUrl: link.linkUrl,
favorites: link.favorites + 1
};
} else {
return link;
}
});
}
return state;
}
import * as linkActions from '../actions/linkActions';
import linkReducer from './linkReducer';
describe('Favorite reducer', function() {
it('should increment the favorite count for a link', () => {
const stateBefore = [
{
linkUrl: 'http://www.csszengarden.com',
favorites: 10
},
{
linkUrl: 'https://daringfireball.net',
favorites: 15
}
];
const action = linkActions.incrementFavorites('http://www.csszengarden.com');
const stateAfter = [
{
linkUrl: 'http://www.csszengarden.com',
favorites: 11
},
{
linkUrl: 'https://daringfireball.net',
favorites: 15
}
];
const result = linkReducer(stateBefore, action);
expect(result).toEqual(stateAfter);
});
it('should not increment any favorite count if the link is not in the state', () => {
const stateBefore = [
{
linkUrl: 'http://www.csszengarden.com',
favorites: 10
},
{
linkUrl: 'https://daringfireball.net',
favorites: 15
}
];
const action = linkActions.incrementFavorites('http://www.buzzfeed.com');
const stateAfter = [
{
linkUrl: 'http://www.csszengarden.com',
favorites: 10
},
{
linkUrl: 'https://daringfireball.net',
favorites: 15
}
];
const result = linkReducer(stateBefore, action);
expect(result).toEqual(stateAfter);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment