Cabuy
Cabuy

Reputation: 43

Jest testing of react-router

I am trying to write a simple jest test for a react-router Route module.

The component has a button and when clicking on it, there is a programatic navigation to another route by using the 'transitionTo' method.

I keep getting the following error, even after adding the stubRouterContext utils (as explained here), and wrapping my UserDetails component in the stubRouterContext:

TypeError: Property 'transitionTo' of object #<Object> is not a function

I am using react 12.2, react-router 12.4, and jest 2.2

My dummy component:

var Navigation, React, Router;

React = require('react/addons');
Router = require('react-router');
Navigation = require('react-router').Navigation;

module.exports = React.createClass({

  mixins: [Navigation],

  onButtonClick: function() {
    this.transitionTo('next-page');
  },

  render: function() {
    return (<button onClick={@onButtonClick}>Go to next page</button>)
  }
});

My test file:

jest.dontMock('./../utils/stub-router-context')
    .dontMock('../dummy-component');

describe('DummyComponent', function() {
  it('let you navigate to next page', function() {

    var React = require('react/addons');
    var TestUtils = React.addons.TestUtils;
    var stubRouterContext = require('./../utils/stub-router-context');
    var DummyComponent = require('../dummy-component');

    var Subject = stubRouterContext(DummyComponent);
    dummyComponent = TestUtils.renderIntoDocument(<Subject/>);

    button = TestUtils.findRenderedDOMComponentWithTag(dummyComponent, 'button');
    React.addons.TestUtils.Simulate.click(button);

  });
});

My stub-router-context.cjsx file:

var React = require('react/addons');
var func = React.PropTypes.func;
var _ = require('lodash');

module.exports  = function(Component, props, stubs) {
  return React.createClass({
    childContextTypes: {
      makePath: func,
      makeHref: func,
      transitionTo: func,
      replaceWith: func,
      goBack: func,
      getCurrentPath: func,
      getCurrentRoutes: func,
      getCurrentPathname: func,
      getCurrentParams: func,
      getCurrentQuery: func,
      isActive: func
    },
    getChildContext: function() {
      return _.merge({}, {
        makePath: function() {},
        makeHref: function() {},
        transitionTo: function() {},
        replaceWith: function() {},
        goBack: function() {},
        getCurrentPath: function() {},
        getCurrentRoutes: function() {},
        getCurrentPathname: function() {},
        getCurrentParams: function() {},
        getCurrentQuery: function() {},
        isActive: function() {}
      }, stubs);
    },
    render: function() {
      return React.createElement(Component, props);
    }
  });
};

Upvotes: 1

Views: 2296

Answers (2)

Chiedo
Chiedo

Reputation: 7564

I whipped up and wrote about a fix based on some code the maintainers wrote. Hopefully it helps!

https://labs.chie.do/jest-testing-with-react-router/

Upvotes: 1

Stan Smith
Stan Smith

Reputation: 906

You need access to React's context feature. Add contextTypes to your class...

module.exports = React.createClass({
  contextTypes: {
    router: React.PropTypes.func
  },

  ...

Then call transitionTo using the context.router like:

this.context.router.transitionTo('Ads', {adID: 100});

Additional information can be found here:

https://github.com/rackt/react-router/blob/master/docs/api/RouterContext.md

Jfyi: I'm currently using React 13.1 and React-router 13.2

Upvotes: 1

Related Questions