【问题标题】:How can I test React Router with Jest?如何使用 Jest 测试 React Router?
【发布时间】:2015-10-12 20:09:53
【问题描述】:

我无法使用context 成功测试React Router。我正在使用

  • 反应 0.13.3
  • 反应路由器 0.13.3
  • 开玩笑 0.3.0
  • 节点 0.10.33

并尝试过以下方法:

有确定的例子吗?

this question(不使用 Jest)中提到的 "super-secret guide" 的所有链接现在都已损坏。当我能够查看该指南时,它没有提供比上面列出的第一个链接更多的信息。

【问题讨论】:

标签: unit-testing reactjs react-router jestjs


【解决方案1】:

不确定这是否正是您要寻找的,但我通过创建一个辅助函数来解决这个问题,该函数在为依赖于路由器状态的组件编写开玩笑测试时使用。

//router-test-helper
var Router = require('react-router'),
    Route = Router.Route,
    TestLocation = require('react-router/lib/locations/TestLocation');

module.exports = function(React){
    TestUtils = React.addons.TestUtils;
    return {
        getRouterComponent: function(targetComponent, mockProps) {
            var component,
                div = document.createElement('div'),
                routes = [
                    React.createFactory(Route)({
                        name: '/',
                        handler: targetComponent
                    })
                ];

            location = new TestLocation('/');
            Router.run(routes, location, function (Handler) {
                var mainComponent = React.render(React.createFactory(Handler)(mockProps), div);
                component = TestUtils.findRenderedComponentWithType(mainComponent, targetComponent);
            });
            return component;
        }
    };
};

所有这些都不是我一个人写的,我想大部分都是我从你链接到的那个现已失效的指南中提取的。如果我没记错的话……已经有一段时间了。

在你拥有它之后,你可以在你的测试中使用它,有点像这样。

//test-example
jest.dontMock('../src/js/someComponent');
var React = require('react/addons');
var TestUtils = React.addons.TestUtils;
var routerHelper = require('../router-test-helper')(React);
var SomeComponent = require('../srcs/js/someComponent');

describe('Some Component', function(){
    it('should be testable', function(){
        var mockProps = {}; 
        var renderedComponent = routerHelper.getRouterComponent(SomeComponent, mockProps);
        // Test your component as usual from here.....
        ///////////////////////////////////////////////

        var inputs = TestUtils.scryRenderedDOMComponentsWithTag(renderedComponent, 'input');
        //blah blah blah
    });
});

这假设你的非模拟模块路径中有 React 和助手

如果您实际上是在尝试测试特定路线的特定内容,或者在路线之间进行转换……我不确定这是否是一个好方法。使用更多的集成测试-y 可能会更好,比如硒或其他东西。另外......一旦反应路由器的 1.0 出来,这可能不会起作用。但是测试'The React Way'(tm)可能更容易,因为所有路由的东西都将通过道具处理。至少那是我从我读过的那一点点得到的印象。

【讨论】:

  • 谢谢@ericf89。我使用您的建议走得更远,但遇到了一些嘲笑问题。在我继续之前,我意识到我不需要使用“上下文”并且应该回到 mixins。我的错误是浏览 v0.13.3 标签上的 GitHub 存储库。我没有看到更新的升级指南,而是关注github.com/rackt/react-router/blob/v0.13.3/UPGRADE_GUIDE.md。再次感谢您的帮助。
【解决方案2】:

对于碰巧遇到此问题的任何人。 这是我最终为我的上下文相关组件设置的设置(当然,为了简单起见):

// dontmock.config.js contains jest.dontMock('components/Breadcrumbs')
// to avoid issue with hoisting of import operators, which causes 
// jest.dontMock() to be ignored

import dontmock from 'dontmock.config.js';
import React from "react";
import { Router, createMemoryHistory } from "react-router";
import TestUtils from "react-addons-test-utils";

import Breadcrumbs from "components/Breadcrumbs";

// Create history object to operate with in non-browser environment
const history = createMemoryHistory("/products/product/12");

// Setup routes configuration.
// JSX would also work, but this way it's more convenient to specify custom 
// route properties (excludes, localized labels, etc..).
const routes = [{
  path: "/",
  component: React.createClass({
    render() { return <div>{this.props.children}</div>; }
  }),
  childRoutes: [{
    path: "products",
    component: React.createClass({
      render() { return <div>{this.props.children}</div>; }
    }),
    childRoutes: [{
      path: "product/:id",
      component: React.createClass({
        // Render your component with contextual route props or anything else you need
        // If you need to test different combinations of properties, then setup a separate route configuration.
        render() { return <Breadcrumbs routes={this.props.routes} />; }
      }),
      childRoutes: []
    }]
  }]
}];

describe("Breadcrumbs component test suite:", () => {
  beforeEach(function() {
    // Render the entire route configuration with Breadcrumbs available on a specified route
    this.component = TestUtils.renderIntoDocument(<Router routes={routes} history={history} />);
    this.componentNode = ReactDOM.findDOMNode(this.component);
    this.breadcrumbNode = ReactDOM.findDOMNode(this.component).querySelector(".breadcrumbs");
  });

  it("should be defined", function() {
    expect(this.breadcrumbNode).toBeDefined();
  });

  /**
   * Now test whatever you need to
   */

【讨论】:

    猜你喜欢
    • 2017-11-26
    • 2017-11-10
    • 2019-02-20
    • 1970-01-01
    • 2017-11-26
    • 2015-01-08
    • 2018-02-25
    • 1970-01-01
    相关资源
    最近更新 更多