How to test RefreshControl "pull-to-refresh" behavior?
See original GitHub issueEnvironment
react-native
: v0.65.1jest
: v27.1.0@testing-library/react-native
: v7.2.0
Ask your Question
I have a component running a GraphQL query (ApolloClient), and rendering a <ScrollView /> with a <RefreshControl /> that triggers the query’s refetch
function:
// MyComponent.tsx
import React from 'react';
import { ActivityIndicator, RefreshControl, ScrollView, ScrollViewProps, Text } from 'react-native';
import { useQuery, gql } from '@apollo/client';
export const TEST_QUERY = gql`
query TestQuery {
test {
placeholder
}
}
`;
export interface TestQueryResponse {
test: {
placeholder: string;
};
}
const MyComponent: React.FC<ScrollViewProps> = (props) => {
const { data, loading, refetch } = useQuery<TestQueryResponse>(TEST_QUERY);
return (
<ScrollView
{...props}
refreshControl={<RefreshControl refreshing={loading} onRefresh={refetch} />}
>
{loading ? (
<ActivityIndicator accessibilityLabel='loading' />
) : data?.test ? (
<Text>{data.test.placeholder}</Text>
) : null}
</ScrollView>
);
};
export default MyComponent;
Now, I would like to test the “refetch” behavior. I thought I would try to fire a “refetch” event on the ScrollView:
// MyComponent.test.tsx
import 'react-native';
import React from 'react';
import { MockedProvider } from '@apollo/client/testing';
import { fireEvent, render } from '@testing-library/react-native';
import MyComponent, { TEST_QUERY } from './MyComponent';
describe('MyComponent', () => {
test('refetch the query when pulled', async () => {
// I have setup a custom render method using <MockedProvider /> as a wrapper,
// This is a simplified inline version of my case:
const { findByText, getByTestId, getByA11yLabel } = render(
<MockedProvider
addTypename={false}
mocks={[
{
request: {
query: TEST_QUERY,
variables: {},
},
result: {
data: {
test: {
placeholder: 'Hello World',
},
},
},
},
]}
>
<MyComponent testID='my-component' />
</MockedProvider>,
);
// wait for initial query to be done loading
await findByText('Hello World');
// attempt to simulate a "pulling" event
fireEvent(getByTestId('my-component'), 'refresh');
// --> No handler function found for event: "refresh"
// expect the <ActivityIndicator /> to be rendered
expect(getByA11yLabel('loading')).toBeDefined();
});
});
But this test case throws an error on the “fireEvent” line:
No handler function found for event: “refresh”
Am I doing something wrong with the API here?
Should I mock something specifically (like <RefreshControl />
itself for this scenario?
(or is there a better way to assert that behavior?)
I did not find a list of “events” that can be fired, but from what I understand of the fireEvent
API, it seems to expect an onRefresh
handler to exists on the target element.
Which indeed is not the case here, since the onRefresh
handler is defined on the <RefreshControl />
component itself.
If the snippets are not enough, I am happy to provide a repository or such?
Issue Analytics
- State:
- Created 2 years ago
- Reactions:3
- Comments:9 (2 by maintainers)
Top GitHub Comments
Please find below steps to call Pull to Refresh.
I have added the below Example for reference.
I understand your point but in my case, it was plain and simple. My whole target was to achieve maximum coverage so to do that I just called the prop to full fill my requirement.