From 7a5fc1cc6e4584a93fceb6fd7195a0cb1371a6ff Mon Sep 17 00:00:00 2001 From: Richard Willis Date: Tue, 21 Jul 2015 20:53:42 +0100 Subject: [PATCH] Added mocking example. Refs #18 --- README.md | 4 +- app/components/Menu/Menu.jsx | 17 ++------- app/components/Menu/MenuItem.jsx | 16 ++++++++ app/components/Menu/__tests__/Menu-test.jsx | 42 +++++++++++++++++++++ package.json | 6 ++- webpack/loaders.js | 4 +- 6 files changed, 71 insertions(+), 18 deletions(-) create mode 100644 app/components/Menu/MenuItem.jsx create mode 100644 app/components/Menu/__tests__/Menu-test.jsx diff --git a/README.md b/README.md index fac5b6b..3f913dd 100644 --- a/README.md +++ b/README.md @@ -79,12 +79,13 @@ export default class Menu extends Component { ###Writing tests: ```js -// Filename: __tests__/Menu-test.js +// Filename: __tests__/Menu-test.jsx 'use strict'; import React from 'react/addons'; import Menu from '../Menu.jsx'; +import { expect } from 'chai'; let { TestUtils } = React.addons; @@ -104,6 +105,7 @@ describe('Menu', () => { expect(menuElem.querySelectorAll('li').length).to.equal(2); }); }); + ``` ## Sass, CSS & webpack diff --git a/app/components/Menu/Menu.jsx b/app/components/Menu/Menu.jsx index e46a0f2..0d97d97 100644 --- a/app/components/Menu/Menu.jsx +++ b/app/components/Menu/Menu.jsx @@ -1,7 +1,6 @@ -// Filename: Menu.jsx - import './_Menu.scss'; import React from 'react'; +import MenuItem from './MenuItem'; let { Component, PropTypes } = React; @@ -15,20 +14,12 @@ export default class Menu extends Component { items: PropTypes.array.isRequired }; - state = { - foo: false - } - - renderItem(item) { - return ( -
  • {item.label}
  • - ); - } - render() { return ( ); } diff --git a/app/components/Menu/MenuItem.jsx b/app/components/Menu/MenuItem.jsx new file mode 100644 index 0000000..91b8461 --- /dev/null +++ b/app/components/Menu/MenuItem.jsx @@ -0,0 +1,16 @@ +import React from 'react'; + +let { Component, PropTypes } = React; + +export default class MenuItem extends Component { + + static propTypes = { + item: PropTypes.object.isRequired + }; + + render() { + return ( +
  • {this.props.item.label}
  • + ); + } +} diff --git a/app/components/Menu/__tests__/Menu-test.jsx b/app/components/Menu/__tests__/Menu-test.jsx new file mode 100644 index 0000000..3edbd17 --- /dev/null +++ b/app/components/Menu/__tests__/Menu-test.jsx @@ -0,0 +1,42 @@ +import React from 'react/addons'; +import { expect } from 'chai'; + +import Menu from '../Menu.jsx'; +import MenuItem from '../MenuItem.jsx'; + +// Here we create a mocked MenuItem component. +class MockedMenuItem extends MenuItem { + render() { + return ( +
  • {this.props.item.label}
  • + ); + } +} + +// Here we set the mocked MenuItem component. +Menu.__Rewire__('MenuItem', MockedMenuItem); + +describe('Menu', () => { + + let { TestUtils } = React.addons; + + let menuItems = [ + { id: 1, label: 'Option 1' }, + { id: 2, label: 'Option 2' } + ]; + + let menu = TestUtils.renderIntoDocument( + + ); + let menuElem = React.findDOMNode(menu); + + it('Should render the menu items', () => { + expect(menuElem.querySelectorAll('li').length).to.equal(2); + expect(menuElem.querySelectorAll('li')[0].textContent.trim()).to.equal(menuItems[0].label); + expect(menuElem.querySelectorAll('li')[1].textContent.trim()).to.equal(menuItems[1].label); + }); + + it('Should render the mocked menu item', () => { + expect(menuElem.querySelectorAll('li')[0].className).to.equal('mocked-menu-item'); + }); +}); diff --git a/package.json b/package.json index 92ac1b3..1ae9fd0 100644 --- a/package.json +++ b/package.json @@ -32,9 +32,10 @@ }, "devDependencies": { "autoprefixer-core": "^5.2.1", - "babel-core": "^5.6.15", + "babel-core": "^5.8.3", "babel-eslint": "^3.1.23", "babel-loader": "^5.3.1", + "babel-plugin-rewire": "^0.1.8", "babel-runtime": "^5.6.15", "chai": "^3.0.0", "css-loader": "^0.15.2", @@ -108,6 +109,7 @@ 2, "single" ], + "no-underscore-dangle": 0, "react/display-name": 0, "react/jsx-quotes": 1, "react/jsx-no-undef": 1, @@ -118,7 +120,7 @@ "react/no-did-update-set-state": 1, "react/no-multi-comp": 1, "react/no-unknown-property": 1, - "react/prop-types": 1, + "react/prop-types": 0, "react/react-in-jsx-scope": 1, "react/self-closing-comp": 1, "react/wrap-multilines": 1 diff --git a/webpack/loaders.js b/webpack/loaders.js index f504f5a..ca97293 100644 --- a/webpack/loaders.js +++ b/webpack/loaders.js @@ -32,7 +32,7 @@ if (DEBUG || TEST) { if (!TEST) { jsxLoader.push('react-hot'); } - jsxLoader.push('babel-loader?optional[]=runtime&stage=0'); + jsxLoader.push('babel-loader?optional[]=runtime&stage=0&plugins=rewire'); sassParams.push('sourceMap', 'sourceMapContents=true'); sassLoader = [ 'style-loader', @@ -46,7 +46,7 @@ if (DEBUG || TEST) { 'postcss-loader' ].join('!'); } else { - jsxLoader = ['babel-loader?optional[]=runtime&stage=0']; + jsxLoader = ['babel-loader?optional[]=runtime&stage=0&plugins=rewire']; sassLoader = ExtractTextPlugin.extract('style-loader', [ 'css-loader', 'postcss-loader',