Skip to content

Commit 3e125d2

Browse files
authored
Remove use of getByTestID in documentation and tests (#294)
* Switched most tests from using test IDs * Docs updated to use alternatives
1 parent ae3d4af commit 3e125d2

File tree

7 files changed

+82
-75
lines changed

7 files changed

+82
-75
lines changed

docs/API.md

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -118,36 +118,36 @@ Get the rendered component JSON representation, e.g. for snapshot testing.
118118
## `cleanup`
119119

120120
```ts
121-
const cleanup: () => void
121+
const cleanup: () => void;
122122
```
123123

124124
Unmounts React trees that were mounted with `render`.
125125

126126
For example, if you're using the `jest` testing framework, then you would need to use the `afterEach` hook like so:
127127

128128
```jsx
129-
import { cleanup, render } from 'react-native-testing-library'
130-
import { View } from 'react-native'
129+
import { cleanup, render } from 'react-native-testing-library';
130+
import { View } from 'react-native';
131131

132-
afterEach(cleanup)
132+
afterEach(cleanup);
133133

134134
it('renders a view', () => {
135-
render(<View />)
135+
render(<View />);
136136
// ...
137-
})
137+
});
138138
```
139139

140140
The `afterEach(cleanup)` call also works in `describe` blocks:
141141

142142
```jsx
143143
describe('when logged in', () => {
144-
afterEach(cleanup)
144+
afterEach(cleanup);
145145

146146
it('renders the user', () => {
147-
render(<SiteHeader />)
147+
render(<SiteHeader />);
148148
// ...
149149
});
150-
})
150+
});
151151
```
152152

153153
Failing to call `cleanup` when you've called `render` could result in a memory leak and tests which are not "idempotent" (which can lead to difficult to debug errors in your tests).
@@ -169,12 +169,13 @@ import { render, fireEvent } from 'react-native-testing-library';
169169

170170
test('fire changeText event', () => {
171171
const onEventMock = jest.fn();
172-
const { getByTestId } = render(
173-
// MyComponent renders TextInput with `onChangeText` bound to handleChangeText
174-
<MyComponent testID="change" handleChangeText={onEventMock} />
172+
const { getByPlaceholder } = render(
173+
// MyComponent renders TextInput which has a placeholder 'Enter details'
174+
// and with `onChangeText` bound to handleChangeText
175+
<MyComponent handleChangeText={onEventMock} />
175176
);
176177

177-
fireEvent(getByTestId('change'), 'onChangeText', 'ab');
178+
fireEvent(getByPlaceholder('change'), 'onChangeText', 'ab');
178179
expect(onEventMock).toHaveBeenCalledWith('ab');
179180
});
180181
```
@@ -215,15 +216,16 @@ import { render, fireEvent } from 'react-native-testing-library';
215216

216217
const onPressMock = jest.fn();
217218

218-
const { getByTestId } = render(
219+
const { getByText } = render(
219220
<View>
220-
<TouchableOpacity onPress={onPressMock} testID="button">
221+
<TouchableOpacity onPress={onPressMock}>
221222
<Text>Press me</Text>
222223
</TouchableOpacity>
223224
</View>
224225
);
225226

226-
fireEvent.press(getByTestId('button'));
227+
fireEvent.press(getByText('Press me'));
228+
expect(onPressMock).toHaveBeenCalled();
227229
```
228230

229231
### `fireEvent.changeText: (element: ReactTestInstance, ...data: Array<any>) => void`
@@ -237,13 +239,13 @@ import { render, fireEvent } from 'react-native-testing-library';
237239
const onChangeTextMock = jest.fn();
238240
const CHANGE_TEXT = 'content';
239241

240-
const { getByTestId } = render(
242+
const { getByPlaceholder } = render(
241243
<View>
242-
<TextInput testID="text-input" onChangeText={onChangeTextMock} />
244+
<TextInput placeholder="Enter data" onChangeText={onChangeTextMock} />
243245
</View>
244246
);
245247

246-
fireEvent.changeText(getByTestId('text-input'), CHANGE_TEXT);
248+
fireEvent.changeText(getByPlaceholder('Enter data'), CHANGE_TEXT);
247249
```
248250

249251
### `fireEvent.scroll: (element: ReactTestInstance, ...data: Array<any>) => void`
@@ -265,13 +267,13 @@ const eventData = {
265267
},
266268
};
267269

268-
const { getByTestId } = render(
269-
<ScrollView testID="scroll-view" onScroll={onScrollMock}>
270+
const { getByText } = render(
271+
<ScrollView onScroll={onScrollMock}>
270272
<Text>XD</Text>
271273
</ScrollView>
272274
);
273275

274-
fireEvent.scroll(getByTestId('scroll-view'), eventData);
276+
fireEvent.scroll(getByText('scroll-view'), eventData);
275277
```
276278

277279
#### On a `FlatList`

docs/Queries.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,7 +203,7 @@ A method returning a `ReactTestInstance` with matching props object
203203

204204
### `ByName`
205205

206-
> This method has been **deprecated** because using it results in fragile tests that may break between minor React Native versions. **DON'T USE IT**. It will be removed in next major release (v2.0). Use [`getByTestId`](#bytestid) instead. It's listed here only for back-compat purposes for early adopters of the library
207-
A method returning a `ReactTestInstance` with matching a React component type. Throws when no matches.
206+
> This method has been **deprecated** because using it results in fragile tests that may break between minor React Native versions. **DON'T USE IT**. It will be removed in next major release (v2.0). Use the other alternatives, such as [`getByText`](#bytext) instead. It's listed here only for back-compat purposes for early adopters of the library
207+
> A method returning a `ReactTestInstance` with matching a React component type. Throws when no matches.
208208
209209
</details>

src/__tests__/act.test.js

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,8 @@ const UseEffect = ({ callback }: { callback: Function }) => {
1414
const Counter = () => {
1515
const [count, setCount] = React.useState(0);
1616

17-
return (
18-
<Text testID="counter" onPress={() => setCount(count + 1)}>
19-
{count}
20-
</Text>
21-
);
17+
const text = `Total count: ${count}`;
18+
return <Text onPress={() => setCount(count + 1)}>{text}</Text>;
2219
};
2320

2421
test('render should trigger useEffect', () => {
@@ -37,12 +34,12 @@ test('update should trigger useEffect', () => {
3734
});
3835

3936
test('fireEvent should trigger useState', () => {
40-
const { getByTestId } = render(<Counter />);
41-
const counter = getByTestId('counter');
37+
const { getByText } = render(<Counter />);
38+
const counter = getByText(/Total count/i);
4239

43-
expect(counter.props.children).toEqual(0);
40+
expect(counter.props.children).toEqual('Total count: 0');
4441
fireEvent.press(counter);
45-
expect(counter.props.children).toEqual(1);
42+
expect(counter.props.children).toEqual('Total count: 1');
4643
});
4744

4845
test('should act even if there is no act in react-test-renderer', () => {

src/__tests__/fireEvent.test.js

Lines changed: 40 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -9,59 +9,63 @@ import {
99
} from 'react-native';
1010
import { render, fireEvent } from '..';
1111

12-
const OnPressComponent = ({ onPress }) => (
12+
const OnPressComponent = ({ onPress, text }) => (
1313
<View>
14-
<TouchableOpacity onPress={onPress} testID="button">
15-
<Text testID="text-button">Press me</Text>
14+
<TouchableOpacity onPress={onPress}>
15+
<Text>{text}</Text>
1616
</TouchableOpacity>
1717
</View>
1818
);
1919

2020
const WithoutEventComponent = () => (
2121
<View>
22-
<Text testID="text">Content</Text>
22+
<Text>Without event</Text>
2323
</View>
2424
);
2525

2626
const CustomEventComponent = ({ onCustomEvent }) => (
2727
<TouchableOpacity onPress={onCustomEvent}>
28-
<Text>Click me</Text>
28+
<Text>Custom event component</Text>
2929
</TouchableOpacity>
3030
);
3131

32-
const MyCustomButton = ({ handlePress }) => (
33-
<OnPressComponent onPress={handlePress} />
32+
const MyCustomButton = ({ handlePress, text }) => (
33+
<OnPressComponent onPress={handlePress} text={text} />
3434
);
3535

3636
const CustomEventComponentWithCustomName = ({ handlePress }) => (
37-
<MyCustomButton testID="my-custom-button" handlePress={handlePress} />
37+
<MyCustomButton handlePress={handlePress} text="Custom component" />
3838
);
3939

4040
describe('fireEvent', () => {
4141
test('should invoke specified event', () => {
4242
const onPressMock = jest.fn();
43-
const { getByTestId } = render(<OnPressComponent onPress={onPressMock} />);
43+
const { getByText } = render(
44+
<OnPressComponent onPress={onPressMock} text="Press me" />
45+
);
4446

45-
fireEvent(getByTestId('button'), 'press');
47+
fireEvent(getByText('Press me'), 'press');
4648

4749
expect(onPressMock).toHaveBeenCalled();
4850
});
4951

5052
test('should invoke specified event on parent element', () => {
5153
const onPressMock = jest.fn();
52-
const { getByTestId } = render(<OnPressComponent onPress={onPressMock} />);
53-
54-
fireEvent(getByTestId('text-button'), 'press');
54+
const text = 'New press text';
55+
const { getByText } = render(
56+
<OnPressComponent onPress={onPressMock} text={text} />
57+
);
5558

59+
fireEvent(getByText(text), 'press');
5660
expect(onPressMock).toHaveBeenCalled();
5761
});
5862

5963
test('should throw an Error when event handler was not found', () => {
60-
const { getByTestId } = render(
64+
const { getByText } = render(
6165
<WithoutEventComponent onPress={() => 'this is not passed to children'} />
6266
);
6367

64-
expect(() => fireEvent(getByTestId('text'), 'press')).toThrow(
68+
expect(() => fireEvent(getByText('Without event'), 'press')).toThrow(
6569
'No handler function found for event: "press"'
6670
);
6771
});
@@ -70,23 +74,26 @@ describe('fireEvent', () => {
7074
const handlerMock = jest.fn();
7175
const EVENT_DATA = 'event data';
7276

73-
const { getByTestId } = render(
77+
const { getByText } = render(
7478
<View>
75-
<CustomEventComponent testID="custom" onCustomEvent={handlerMock} />
79+
<CustomEventComponent onCustomEvent={handlerMock} />
7680
</View>
7781
);
7882

79-
fireEvent(getByTestId('custom'), 'customEvent', EVENT_DATA);
83+
fireEvent(getByText('Custom event component'), 'customEvent', EVENT_DATA);
8084

8185
expect(handlerMock).toHaveBeenCalledWith(EVENT_DATA);
8286
});
8387
});
8488

8589
test('fireEvent.press', () => {
8690
const onPressMock = jest.fn();
87-
const { getByTestId } = render(<OnPressComponent onPress={onPressMock} />);
91+
const text = 'Fireevent press';
92+
const { getByText } = render(
93+
<OnPressComponent onPress={onPressMock} text={text} />
94+
);
8895

89-
fireEvent.press(getByTestId('text-button'));
96+
fireEvent.press(getByText(text));
9097

9198
expect(onPressMock).toHaveBeenCalled();
9299
});
@@ -101,13 +108,13 @@ test('fireEvent.scroll', () => {
101108
},
102109
};
103110

104-
const { getByTestId } = render(
105-
<ScrollView testID="scroll-view" onScroll={onScrollMock}>
111+
const { getByText } = render(
112+
<ScrollView onScroll={onScrollMock}>
106113
<Text>XD</Text>
107114
</ScrollView>
108115
);
109116

110-
fireEvent.scroll(getByTestId('scroll-view'), eventData);
117+
fireEvent.scroll(getByText('XD'), eventData);
111118

112119
expect(onScrollMock).toHaveBeenCalledWith(eventData);
113120
});
@@ -116,37 +123,40 @@ test('fireEvent.changeText', () => {
116123
const onChangeTextMock = jest.fn();
117124
const CHANGE_TEXT = 'content';
118125

119-
const { getByTestId } = render(
126+
const { getByPlaceholder } = render(
120127
<View>
121-
<TextInput testID="text-input" onChangeText={onChangeTextMock} />
128+
<TextInput
129+
placeholder="Customer placeholder"
130+
onChangeText={onChangeTextMock}
131+
/>
122132
</View>
123133
);
124134

125-
fireEvent.changeText(getByTestId('text-input'), CHANGE_TEXT);
135+
fireEvent.changeText(getByPlaceholder('Customer placeholder'), CHANGE_TEXT);
126136

127137
expect(onChangeTextMock).toHaveBeenCalledWith(CHANGE_TEXT);
128138
});
129139

130140
test('custom component with custom event name', () => {
131141
const handlePress = jest.fn();
132142

133-
const { getByTestId } = render(
143+
const { getByText } = render(
134144
<CustomEventComponentWithCustomName handlePress={handlePress} />
135145
);
136146

137-
fireEvent(getByTestId('my-custom-button'), 'handlePress');
147+
fireEvent(getByText('Custom component'), 'handlePress');
138148

139149
expect(handlePress).toHaveBeenCalled();
140150
});
141151

142152
test('event with multiple handler parameters', () => {
143153
const handlePress = jest.fn();
144154

145-
const { getByTestId } = render(
155+
const { getByText } = render(
146156
<CustomEventComponentWithCustomName handlePress={handlePress} />
147157
);
148158

149-
fireEvent(getByTestId('my-custom-button'), 'handlePress', 'param1', 'param2');
159+
fireEvent(getByText('Custom component'), 'handlePress', 'param1', 'param2');
150160

151161
expect(handlePress).toHaveBeenCalledWith('param1', 'param2');
152162
});

src/__tests__/render.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ test('getAllByTestId, queryAllByTestId', () => {
110110
});
111111

112112
test('getByName, queryByName', () => {
113-
const { getByTestId, getByName, queryByName } = render(<Banana />);
114-
const bananaFresh = getByTestId('bananaFresh');
113+
const { getByText, getByName, queryByName } = render(<Banana />);
114+
const bananaFresh = getByText('not fresh');
115115
const button = getByName('Button');
116116

117117
button.props.onPress();

src/__tests__/shallow.test.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ test('shallow rendering React elements', () => {
2020
});
2121

2222
test('shallow rendering React Test Instance', () => {
23-
const { getByTestId } = render(<TextPress />);
24-
const { output } = shallow(getByTestId('text-button'));
23+
const { getByText } = render(<TextPress />);
24+
const { output } = shallow(getByText('Press me'));
2525

2626
expect(output).toMatchSnapshot();
2727
});

src/__tests__/waitForElement.test.js

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class Banana extends React.Component<any> {
1111
render() {
1212
return (
1313
<View>
14-
{this.props.fresh && <Text testID="fresh">Fresh</Text>}
14+
{this.props.fresh && <Text>Fresh</Text>}
1515
<TouchableOpacity onPress={this.changeFresh}>
1616
<Text>Change freshness!</Text>
1717
</TouchableOpacity>
@@ -36,25 +36,23 @@ class BananaContainer extends React.Component<{}, any> {
3636
}
3737

3838
test('waits for element until it stops throwing', async () => {
39-
const { getByTestId, getByName, queryByTestId } = render(<BananaContainer />);
39+
const { getByText, getByName, queryByText } = render(<BananaContainer />);
4040

4141
fireEvent.press(getByName('TouchableOpacity'));
4242

43-
expect(queryByTestId('fresh')).toBeNull();
43+
expect(queryByText('Fresh')).toBeNull();
4444

45-
const freshBananaText = await waitForElement(() => getByTestId('fresh'));
45+
const freshBananaText = await waitForElement(() => getByText('Fresh'));
4646

4747
expect(freshBananaText.props.children).toBe('Fresh');
4848
});
4949

5050
test('waits for element until timeout is met', async () => {
51-
const { getByTestId, getByName } = render(<BananaContainer />);
51+
const { getByText, getByName } = render(<BananaContainer />);
5252

5353
fireEvent.press(getByName('TouchableOpacity'));
5454

55-
await expect(
56-
waitForElement(() => getByTestId('fresh'), 100)
57-
).rejects.toThrow();
55+
await expect(waitForElement(() => getByText('Fresh'), 100)).rejects.toThrow();
5856
});
5957

6058
test('waits for element with custom interval', async () => {

0 commit comments

Comments
 (0)