-
Notifications
You must be signed in to change notification settings - Fork 114
/
ConnectedClasses.test.js
165 lines (158 loc) · 8.85 KB
/
ConnectedClasses.test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import expect from 'expect';
import ReactTestUtils from 'react-addons-test-utils';
import {shallow, mount} from 'enzyme';
//These are used to pass a mock store down through nested components
import configureStore from 'redux-mock-store';
import { Provider } from 'react-redux';
import InnerConnectConnected, {InnerConnect} from '../../localSrc/InnerConnect';
import OuterConnectConnected, {OuterConnect} from '../../localSrc/OuterConnect';
/*************************************************************************************
These tests provide an example of testing nested React components that use Redux via its connect function
The conclusions from this work are:
- Export the React component class (without the connect) so you can test it in isolation.
You can then shallow render without supplying the Redux store via the <Provider> class.
- Enzyme's mount (i.e. fully rendered) test approach is then the best way to test it,
but you HAVE to supply a store via the Redux <Provider> class if the nested components use Redux.
****************************************************************************************/
describe('localSrc/InnerConnect and OuterConnect (example of testing nested, decorated components)', () => {
describe('enzyme', () => {
describe('shallow', () => {
it('InnerConnect, no connect', () => {
const wrapper = shallow(<InnerConnect />);
expect(wrapper.find('h2').length).toBe(1);
expect(wrapper.find('h2').text()).toBe('Inner.dispatch undefined');
});
it('InnerConnectConnected, with connect', () => {
const mockStore = configureStore([]);
const store = mockStore({});
const wrapper = shallow(<Provider store={store}>
<InnerConnectConnected />
</Provider>);
expect(wrapper.text()).toBe('<Connect(InnerConnect) />');
});
it('OuterConnect, with no connect', () => {
const wrapper = shallow(<OuterConnect />);
expect(wrapper.text()).toBe('Outer.dispatch undefined<Connect(InnerConnect) />');
});
it('OuterConnect, with connect', () => {
const mockStore = configureStore([]);
const store = mockStore({});
const wrapper = shallow(<Provider store={store}>
<OuterConnect />
</Provider>);
expect(wrapper.text()).toBe('<OuterConnect />');
});
});
describe('mount', () => {
it('InnerConnect, no connect', () => {
const wrapper = mount(<InnerConnect />);
expect(wrapper.find('h2').length).toBe(1);
expect(wrapper.find('h2').text()).toBe('Inner.dispatch undefined');
});
it('InnerConnectConnected, with connect', () => {
const mockStore = configureStore([]);
const store = mockStore({});
const wrapper = mount(<Provider store={store}>
<InnerConnectConnected />
</Provider>);
expect(wrapper.find('h2').length).toBe(1);
expect(wrapper.find('h2').text()).toBe('Inner.dispatch defined');
});
//This fails with the following error:
//Invariant Violation: Could not find "store" in either the context or props of "Connect(InnerConnect)". Either wrap the root component in a <Provider>, or explicitly pass "store" as a prop to "Connect(InnerConnect)".
it.skip('OuterConnect, with no connect', () => {
const wrapper = mount(<OuterConnect />);
expect(wrapper.text()).toBe('Outer.dispatch undefined<Connect(InnerConnect) />');
});
it('OuterConnectConnected, with connect', () => {
const mockStore = configureStore([]);
const store = mockStore({});
const wrapper = mount(<Provider store={store}>
<OuterConnectConnected />
</Provider>);
expect(wrapper.find('h1').length).toBe(1);
expect(wrapper.find('h1').text()).toBe('Outer.dispatch defined');
expect(wrapper.find('h2').length).toBe(1);
expect(wrapper.find('h2').text()).toBe('Inner.dispatch defined');
});
});
});
//The react-addons-test-utils shallow tests are not very useful (and some fail!)
//I have left them in so you know what happens
describe('react-addons-test-utils (not very useful, or fail)', () => {
describe('shallow', () => {
//This runs fine as we are testing an undecorated react class
it('InnerConnect, no connect', () => {
let renderer = ReactTestUtils.createRenderer();
renderer.render(<InnerConnect />);
const result = renderer.getRenderOutput();
expect(result.type).toBe('h2');
expect(result.props.children).toEqual(['Inner.dispatch ', 'undefined']);
});
//The test below outputs the following error message:
//ERROR: 'Warning: Failed propType: Invalid prop `children` supplied to `Provider`, expected a single ReactElement.'
//... and then fails with error below:
//Invariant Violation: onlyChild must be passed a children with exactly one child
it.skip('InnerConnectConnected, with connect', () => {
const mockStore = configureStore([]);
const store = mockStore({});
let renderer = ReactTestUtils.createRenderer();
renderer.render(<Provider store={store}> <InnerConnectConnected /> </Provider>);
const result = renderer.getRenderOutput();
expect(result.type).toBe('h2');
expect(result.props.children).toEqual(['Inner.dispatch ', 'defined']);
});
//this test runs fine, but it doesn't produce any useful output.
it('OuterConnectConnected, with connect',
() => {
const mockStore = configureStore([]);
const store = mockStore({});
let renderer = ReactTestUtils.createRenderer();
renderer.render(<Provider store={store}>
<OuterConnectConnected />
</Provider>);
const result = renderer.getRenderOutput();
//it picks up the connect function
expect(typeof result.type).toBe('function');
//I didn't find anything else that was useful to check.
});
});
describe('renderIntoDocument', () => {
it('InnerConnect, no connect', () => {
const rendered = ReactTestUtils.renderIntoDocument(<InnerConnect />);
const node = ReactDOM.findDOMNode(rendered);
expect(node.tagName).toBe('H2');
expect(node.textContent).toEqual('Inner.dispatch undefined');
});
//The test below outputs the following error message:
//ERROR: 'Warning: Failed propType: Invalid prop `children` supplied to `Provider`, expected a single ReactElement.'
//... and then fails with error below:
//Invariant Violation: onlyChild must be passed a children with exactly one child
it.skip('InnerConnectConnected, with connect', () => {
const mockStore = configureStore([]);
const store = mockStore({});
const rendered = ReactTestUtils.renderIntoDocument(
<Provider store={store}> <InnerConnectConnected /> </Provider>);
const node = ReactDOM.findDOMNode(rendered);
expect(node.tagName).toBe('H2');
expect(node.textContent).toEqual('Inner.dispatch defined');
});
//The test below outputs the following error message:
//ERROR: 'Warning: Failed propType: Invalid prop `children` supplied to `Provider`, expected a single ReactElement.'
//... and then fails with error below:
//Invariant Violation: onlyChild must be passed a children with exactly one child
it.skip('OuterConnectConnected, with connect',
() => {
const mockStore = configureStore([]);
const store = mockStore({});
const rendered = ReactTestUtils.renderIntoDocument(
<Provider store={store}> <OuterConnectConnected /> </Provider>);
const node = ReactDOM.findDOMNode(rendered);
expect(node.tagName).toBe('H2');
expect(node.textContent).toEqual('Inner.dispatch defined');
});
});
});
});