Skip to content

Commit d1a79b2

Browse files
committed
made the testing guide
1 parent f878bf3 commit d1a79b2

File tree

1 file changed

+145
-0
lines changed

1 file changed

+145
-0
lines changed

docs/guides/testing.md

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,149 @@
11
React Router Testing
22
====================
33

4+
Because the router relies heavily on the lesser known `context` feature
5+
of React, it can be a pain in the neck to test your components that have
6+
things like `<Link>` or mixin `State` and `Navigation`.
7+
8+
You simply have to stub out the context you need.
9+
10+
```js
11+
// this will yell at you if you have `<Link>` and friends
12+
React.render(<IndividualComponent/>, testElement);
13+
```
14+
15+
You'll get something like:
16+
17+
```
18+
"Warning: Required context `makePath` was not specified in `Link`. Check the render method of `IndividualComponent`."
19+
"Warning: Required context `makeHref` was not specified in `Link`. Check the render method of `IndividualComponent`."
20+
"Warning: Required context `transitionTo` was not specified in `Link`. Check the render method of `IndividualComponent`."
21+
"Warning: Required context `replaceWith` was not specified in `Link`. Check the render method of `IndividualComponent`."
22+
"Warning: Required context `goBack` was not specified in `Link`. Check the render method of `IndividualComponent`."
23+
"Warning: Required context `getCurrentPath` was not specified in `Link`. Check the render method of `IndividualComponent`."
24+
"Warning: Required context `getCurrentRoutes` was not specified in `Link`. Check the render method of `IndividualComponent`."
25+
"Warning: Required context `getCurrentPathname` was not specified in `Link`. Check the render method of `IndividualComponent`."
26+
"Warning: Required context `getCurrentParams` was not specified in `Link`. Check the render method of `IndividualComponent`."
27+
"Warning: Required context `getCurrentQuery` was not specified in `Link`. Check the render method of `IndividualComponent`."
28+
"Warning: Required context `isActive` was not specified in `Link`. Check the render method of `IndividualComponent`."
29+
```
30+
31+
So we can just wrap up the thing we want to test in a different
32+
component and stub out the `context` stuff.
33+
34+
```js
35+
// wrap it up first:
36+
var { func } = React.PropTypes;
37+
38+
var TestWrapper = React.createClass({
39+
childContextTypes: {
40+
makePath: func,
41+
makeHref: func,
42+
transitionTo: func,
43+
replaceWith: func,
44+
goBack: func,
45+
getCurrentPath: func,
46+
getCurrentRoutes: func,
47+
getCurrentPathname: func,
48+
getCurrentParams: func,
49+
getCurrentQuery: func,
50+
isActive: func,
51+
},
52+
53+
getChildContext () {
54+
return {
55+
makePath () {},
56+
makeHref () {},
57+
transitionTo () {},
58+
replaceWith () {},
59+
goBack () {},
60+
getCurrentPath () {},
61+
getCurrentRoutes () {},
62+
getCurrentPathname () {},
63+
getCurrentParams () {},
64+
getCurrentQuery () {},
65+
isActive () {},
66+
};
67+
},
68+
69+
render () {
70+
return <IndividualComponent/>
71+
}
72+
});
73+
74+
// okay, now it'll work:
75+
React.render(<TestWrapper/>, testElement);
76+
```
77+
78+
This is handy because now you can force the code down certain paths if
79+
you add some behavior to the stubbed context. It's also a lot of junk to
80+
write, copy/paste this into your test utils to make things a bit easier:
81+
82+
```js
83+
var stubRouterContext = (Component, props, stubs) => {
84+
return React.createClass({
85+
childContextTypes: {
86+
makePath: func,
87+
makeHref: func,
88+
transitionTo: func,
89+
replaceWith: func,
90+
goBack: func,
91+
getCurrentPath: func,
92+
getCurrentRoutes: func,
93+
getCurrentPathname: func,
94+
getCurrentParams: func,
95+
getCurrentQuery: func,
96+
isActive: func,
97+
},
98+
99+
getChildContext () {
100+
return Object.assign({
101+
makePath () {},
102+
makeHref () {},
103+
transitionTo () {},
104+
replaceWith () {},
105+
goBack () {},
106+
getCurrentPath () {},
107+
getCurrentRoutes () {},
108+
getCurrentPathname () {},
109+
getCurrentParams () {},
110+
getCurrentQuery () {},
111+
isActive () {},
112+
}, stubs);
113+
},
114+
115+
render () {
116+
return <Component {...props} />
117+
}
118+
});
119+
};
120+
```
121+
122+
Now your tests are much simpler:
123+
124+
```js
125+
var stubRouterContext = require('./stubRouterContext');
126+
var IndividualComponent = require('./IndividualComponent');
127+
var Subject = stubRouterContext(IndividualComponent, {someProp: 'foo'});
128+
React.render(<Subject/>, testElement);
129+
```
130+
131+
You can also send code down certain paths if you'd like by supplying
132+
behavior to the stubbed context:
133+
134+
```js
135+
var Subject = stubRouterContext(IndividualComponent, {prop: 'foo'}, {
136+
getCurrentQuery () {
137+
return { modal: true };
138+
}
139+
});
140+
```
141+
142+
Now your test will think it got `?modal=true` in the URL, even though
143+
there is no URL in the test.
144+
145+
Why is `stubRouterContext` not in the project?
146+
----------------------------------------------
147+
148+
I dunno.
4149

0 commit comments

Comments
 (0)