react-native-scrollable-tab-view
react-native-scrollable-tab-view copied to clipboard
[Solution] Using with react-native-testing-library: "Unable to find node on an unmounted component."
trafficstars
I keep running into this issue when attempting to test this component, and I'm just sharing my solution here as I don't have time to create a minimal repro repository.
Feel free to close as desired, just wanted this to be here for others' reference to quickly resolve this issue.
This repros on latest (1.0.0).
I'm attempting to test Apollo Client which requires adding a 0-duration timeout promise to tick over and actually run the query, before testing the "loaded" version of the component.
The error is:
Unable to find node on an unmounted component.
102 | );
103 |
> 104 | const isLoading = () => rr.queryByText(/Loading/) !== null;
| ^
105 | const isShowingData = () => rr.queryByText(/Noooootes/) !== null;
106 |
107 | expect(isLoading()).toBe(true);
at queryByText (src/components/workouts/SelectWorkoutScreen.test.tsx:104:30)
at Object.isLoading (src/components/workouts/SelectWorkoutScreen.test.tsx:112:10)
at tryCatch (node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:45:40)
at Generator.invoke [as _invoke] (node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:274:22)
at Generator.prototype.<computed> [as next] (node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:97:21)
at tryCatch (node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:45:40)
at invoke (node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:135:20)
at node_modules/@babel/runtime/node_modules/regenerator-runtime/runtime.js:145:13
at tryCallOne (node_modules/react-native/node_modules/promise/lib/core.js:37:12)
at node_modules/react-native/node_modules/promise/lib/core.js:123:15
This doesn't happen before the timeout promise, but does after.
Solution
For now I'm resolving with a simple mock:
jest.mock("react-native-scrollable-tab-view", () => {
return {
__esModule: true, // needed to mock the default export
default: (props: { children: ReactNode[] }) => {
// Just render first child
return props.children[0];
},
DefaultTabBar: () => null,
};
});
And here's the test code as FYI:
test("Select Workout screen renders with query", async () => {
const rr = render(
<MockedProvider mocks={[mock, createOnboardingEventsMock()]}>
<SelectWorkoutScreen />
</MockedProvider>,
);
const isLoading = () => rr.queryByText(/Loading/) !== null;
const isShowingData = () => rr.queryByText(/Notes/) !== null;
expect(isLoading()).toBe(true);
expect(isShowingData()).not.toBe(true);
await wait();
expect(isLoading()).not.toBe(true);
expect(isShowingData()).toBe(true);
});
// Wait a tick so the query runs
// https://www.apollographql.com/docs/react/development-testing/testing/#testing-final-state
export async function wait(ms = 0) {
await act(async () => {
return new Promise(resolve => {
setTimeout(resolve, ms);
});
});
}