Unit testing React components with `Link` components is impossible
gregeinfrank opened this issue ยท 12 comments
I know there is this TestLocation: #686
But, it's not clear how this really helps if I want to unit test a component within my views. Something like a side nav, that has a bunch of Link
s, I need to set up routes with the TestLocation if I want to just render the side nav alone to unit test?
Can someone maybe explain how I should be using TestLocation
properly if that fixes my issue?
Thanks!
I just figured this out last night and it was a moderately confusing experience... Un momento.
jest.dontMock('../Logs');
var React;
var TestUtils;
var Logs, LogHandler, Logstore;
var Router, TestLocation;
var routes;
describe('Logs', function() {
beforeEach(function(){
React = require('react/addons');
TestUtils = React.addons.TestUtils;
Logs = require('../Logs');
LogHandler = Logs.LogHandler;
LogStore = Logs.LogStore;
Router = require('react-router');
// Yes, this is officially ok.
TestLocation = require('react-router/modules/locations/TestLocation');
TestLocation.history = ['/logs/all/all/date_desc/1'];
routes = <Router.Route name="logs" path="/logs/:kind/:filter/:sortBy/:page" handler={LogHandler}/>;
});
// Yes, the LogHandler does in fact contain Links.
describe('Filtering', function() {
it('should filter log data', function() {
// Implementation detail for my project.
LogStore.getLogs = jest.genMockFunction().mockReturnValue([
{id: 0, kind: 'transfer' },
{id: 1, kind: 'magicdance' },
{id: 2, kind: 'safetydance' }
]);
Router.run(routes, TestLocation, function(Handler) {
var handler = TestUtils.renderIntoDocument(<Handler />);
// SECRET SAUCE
// ~~~~~~~~~~~~~
// So this was the gotcha for me. The handler was not the component I was
// looking for, but some console.logs showed me the way:
var component = handler.getRouteComponents()[0];
expect(TestUtils.scryRenderedDOMComponentsWithClass(component, 'log-entry').length).toBe(1);
});
});
});
});
I finally pushed this guide, sorry for the trouble. https://github.com/rackt/react-router/blob/master/docs/guides/testing.md
I keep on finding references to this guide in searching for an example on how to test my page handlers, will this be available in the new docs soon?
@ryanflorence unfortunately the reference does not exist
@ryanflorence - your link broke, because it's no longer on master
, here's the tagged version.
https://github.com/rackt/react-router/blob/0.13.x/docs/guides/testing.md
Is there a 1.0 version?
@robcolburn we don't have docs for testing
yet for React Router 1.0.0-RC1. If anyone is up for writing those I'll be happy to merge that PR. If not I try to write something when I find some free time.
Added a new issue for that #2149
Just in case, the link mentioned before in comments is now: https://github.com/rackt/react-router/blob/master/docs/guides/Testing.md
In case you are using react-test-renderer
, you can do the following as well when testing the Landing
component which contains aLink
component:
import React from 'react'
import renderer from 'react-test-renderer'
import { MemoryRouter } from 'react-router'
import Landing from './Landing'
test('Landing renders correctly', () => {
const component = renderer.create(
<MemoryRouter>
<Landing />
</MemoryRouter>
)
const tree = component.toJSON()
expect(tree).toMatchSnapshot()
})
Below is the Landing
component
import React from 'react'
import { Link } from 'react-router-dom'
const Landing = () => (
<div className="landing">
<h1>Movie Library</h1>
<input type="text" placeholder="Search..." />
<Link to="/search">or Browse All</Link>
</div>
)
export default Landing
But do I need to install the whole react-router
library just to test one component which contains a Link
component?
This problem is further compounded when using enzyme
. Enzyme only lets you do things like setState
etc. on the root component you have mounted. This means if you wrap your component that contains a Link
inside a router, then the root component is now the router and you cannot test your component with setState
or update
... as least as far as I can see. Any ideas?
Checkout this project: https://github.com/NullVoxPopuli/react-vs-ember/tree/master/testing/react (specifically that folder)
It demonstrates how to test anything and everything worth testing.
Basically, the solution in two parts:
- Don't use enzyme
- Integration test your components, don't unit test them