React Router Testing With Jest

从 React Router 1.x 版本开始,测试变得简单多了。想知道 React Router 以前版本如何测试,参阅 旧的测试文档

在开始之前,建议你阅读以下前两个教程:

在 React-Router 1.x 中编写测试会很顺利。如果遇到问题,后面会有解法。很多用户在升级旧的 react-router 0.x 项目时会遇到一些问题。

从 React-Router 0.x 到 1.x 带来的测试配置更新

首先,确保你使用的包至少是以下版本:

  • "react": "^0.14.0"
  • "react-dom": "^0.14.0"
  • "react-router": "^1.0.0"
  • "react-addons-test-utils": "^0.14.0"
  • "jest-cli": "^0.5.10"
  • "babel-jest": "^5.3.0"

另外,确保你使用的是 node 4.x

在以前的配置中,react-tools 是必须的。但现在不是了。你要把它从 package.json 和环境中删除。

  1. "react-tools": "~0.13.3",

最后,你有任何类似如下的,需要将:

  1. var React = require('react/addons');
  2. var TestUtils = React.addons.TestUtils;

替换成:

  1. var TestUtils = require('react-addons-test-utils');
  2. var ReactDOM = require('react-dom');
  3. var React = require('react');

不要忘记执行 npm clean、install 等操作。并且确保把 react-addons-test-utils 和 react-dom 加到 unmocked path(非模拟路径)中。

  1. ...
  2. "unmockedModulePathPatterns": [
  3. "./node_modules/react",
  4. "./node_modules/react-dom",
  5. "./node_modules/react-addons-test-utils",
  6. ],
  7. ...

最后,确保使用 babel-jest 做为脚本预处理工具

  1. ...
  2. "scriptPreprocessor": "./node_modules/babel-jest",
  3. ...

示例:

一个组件:

  1. //../components/BasicPage.js
  2. let React = require('react');
  3. import { Button } from 'react-bootstrap';
  4. import { Link } from 'react-router';
  5. let BasicPage =
  6. React.createClass({
  7. propTypes: {
  8. authenticated: React.PropTypes.bool,
  9. },
  10. render:function(){
  11. let mainContent;
  12. let authenticated = this.props.authenticated;
  13. if(authenticated) {
  14. mainContent = (
  15. <div>
  16. <Link to="/admin"><Button bsStyle="primary">Login</Button></Link>
  17. </div>
  18. );
  19. } else {
  20. mainContent = (
  21. <div>
  22. <Link to="/admin"><Button bsStyle="primary">Login</Button></Link>
  23. </div>
  24. );
  25. }
  26. return (
  27. <div>
  28. {mainContent}
  29. </div>
  30. );
  31. },
  32. });
  33. module.exports = BasicPage;

组件测试代码:

  1. //../components/__tests__/BasicPage-test.js
  2. // 注意:不能使用 ES6 模块语法,因为
  3. // jest.dontMock & jest.autoMockOff()
  4. // 还不支持 ES6 模块
  5. jest.dontMock('../BasicPage');
  6. describe('BasicPage', function() {
  7. let BasicPage = require('../BasicPage');
  8. let TestUtils = require('react-addons-test-utils');
  9. let ReactDOM = require('react-dom');
  10. let React = require('react');
  11. it('renders the Login button if not logged in', function() {
  12. let page = TestUtils.renderIntoDocument(<BasicPage />);
  13. let button = TestUtils.findRenderedDOMComponentWithTag(page, 'button');
  14. expect(ReactDOM.findDOMNode(button).textContent).toBe('Login');
  15. });
  16. it('renders the Account button if logged in', function() {
  17. let page = TestUtils.renderIntoDocument(<BasicPage authenticated={true} />);
  18. let button = TestUtils.findRenderedDOMComponentWithTag(page, 'button');
  19. expect(ReactDOM.findDOMNode(button).textContent).toBe('Your Account');
  20. });
  21. });