Testing the useSubscription
hook I'm finding a bit difficult, since the method is omitted/not documented on the Apollo docs (at time of writing). Presumably, it should be mocked using the <MockedProvider />
from @apollo/react-testing
, much like the mutations are in the examples given in that link.
Testing the loading state for a subscription I have working:
Component:
const GET_RUNNING_DATA_SUBSCRIPTION = gql`
subscription OnLastPowerUpdate {
onLastPowerUpdate {
result1,
result2,
}
}
`;
const Dashboard: React.FC<RouteComponentProps & Props> = props => {
const userHasProduct = !!props.user.serialNumber;
const [startGetRunningData] = useMutation(START_GET_RUNNING_DATA);
const [stopGetRunningData] = useMutation(STOP_GET_RUNNING_DATA);
useEffect(() => {
startGetRunningData({
variables: { serialNumber: props.user.serialNumber },
});
return () => {
stopGetRunningData();
};
}, [startGetRunningData, stopGetRunningData, props]);
const SubscriptionData = (): any => {
const { data, loading } = useSubscription(GET_RUNNING_DATA_SUBSCRIPTION);
if (loading) {
return <Heading>Data loading...</Heading>;
}
const metrics = [];
if (data) {
console.log('DATA NEVER CALLED IN TEST!');
}
return metrics;
};
if (!userHasProduct) {
return <Redirect to="/enter-serial" />;
}
return (
<>
<Header />
<PageContainer size="midi">
<Panel>
<SubscriptionData />
</Panel>
</PageContainer>
</>
);
};
And a successful test of the loading state for the subscription:
import React from 'react';
import thunk from 'redux-thunk';
import { createMemoryHistory } from 'history';
import { create } from 'react-test-renderer';
import { Router } from 'react-router-dom';
import wait from 'waait';
import { MockedProvider } from '@apollo/react-testing';
import { Provider } from 'react-redux';
import configureMockStore from 'redux-mock-store';
import Dashboard from './Dashboard';
import {
START_GET_RUNNING_DATA,
STOP_GET_RUNNING_DATA,
GET_RUNNING_DATA_SUBSCRIPTION,
} from './queries';
const mockStore = configureMockStore([thunk]);
const serialNumber = 'AL3286wefnnsf';
describe('Dashboard page', () => {
let store: any;
const fakeHistory = createMemoryHistory();
const mocks = [
{
request: {
query: START_GET_RUNNING_DATA,
variables: {
serialNumber,
},
},
result: {
data: {
startFetchingRunningData: {
startedFetch: true,
},
},
},
},
{
request: {
query: GET_RUNNING_DATA_SUBSCRIPTION,
},
result: {
data: {
onLastPowerUpdate: {
result1: 'string',
result2: 'string'
},
},
},
},
{
request: {
query: STOP_GET_RUNNING_DATA,
},
result: {
data: {
startFetchingRunningData: {
startedFetch: false,
},
},
},
},
];
afterEach(() => {
jest.resetAllMocks();
});
describe('when initialising', () => {
beforeEach(() => {
store = mockStore({
user: {
serialNumber,
token: 'some.token.yeah',
hydrated: true,
},
});
store.dispatch = jest.fn();
});
it('should show a loading state', async () => {
const component = create(
<Provider store={store}>
<MockedProvider mocks={mocks} addTypename={false}>
<Router history={fakeHistory}>
<Dashboard />
</Router>
</MockedProvider>
</Provider>,
);
expect(component.root.findAllByType(Heading)[0].props.children).toBe(
'Data loading...',
);
});
});
});
Adding another test to wait until the data has been resolved from the mocks passed in, as per the instructions on the last example from the docs for testing useMutation, you have to wait for it.
Broken test:
it('should run the data', async () => {
const component = create(
<Provider store={store}>
<MockedProvider mocks={mocks} addTypename={false}>
<Router history={fakeHistory}>
<Dashboard />
</Router>
</MockedProvider>
</Provider>,
);
await wait(0);
});
Error the broken test throws:
No more mocked responses for the query: subscription OnLastPowerUpdate {
Dependencies:
"@apollo/react-common": "^3.1.3",
"@apollo/react-hooks": "^3.1.3",
"@apollo/react-testing": "^3.1.3",
Things I've tried already:
- react-test-renderer / enzyme / @testing-library/react
- awaiting next tick
- initialising the client in the test differently
Github repo with example:
https://github.com/harrylincoln/apollo-subs-testing-issue
Anyone out there able to help?
GET_RUNNING_DATA_SUBSCRIPTION
subscription ? – Govea