I have a component that calls a useApi custom hook. In the custom hook it fetches data from the API an then performs a dispatch action that updates the app state with the data fetched from the API. In my test I'm spying on my 'get' api call and mocking a return value. I'm also mocking my dispatch function and ensuring it's being called with the proper action/data. All of that succeeds, but my component does not reflect the state update.
WorkflowList.test.js
test('Workflow list loads on mount', async () => {
let myComponent;
const apiSpy = jest.spyOn(api, 'get').mockReturnValue({ ...mock.workflow });
const dispatch = jest.fn();
await act(async () => {
myComponent = render(
<GlobalContext.Provider
value={{
...mock.initial,
dispatch,
}}
>
<ThemeProvider theme={light}>
<Router history={history}>
<WorkflowList />
</Router>
</ThemeProvider>
</GlobalContext.Provider>
)
});
await expect(apiSpy).toHaveBeenCalled(); <--- Passes
await expect(dispatch).toHaveBeenCalledWith({ <--- Passes
type: 'LIST_WORKFLOWS',
result: { ...mock.workflow },
});
expect(screen.getByText('Test Workflow 1')).toBeInTheDocument(); <--- Fails
});
The dispatch call doesn't seem to be updating my components state. One this that does work is if I rerender the component and then manually put in the new workflow in my Providers 'value' property. But, that doesn't seem right, it seems like I should be able to run my mock.workflow through and have it update the component.
WorkflowList.js
const WorkflowList = () => {
const classes = useStyles();
const { workflow } = useContext(GlobalContext);
const { loading, get } = useApi();
const listWorkflows = async () => {
await get({
endpoint: '/strategy/strategy',
success: 'LIST_WORKFLOWS',
fail: 'LIST_WORKFLOWS_FAILED'
});
};
// Fetch data and then dispatch a state update depending on success or fail
useMemo(() => {
listWorkflows();
}, []);
return (
<Page
className={classes.root}
title="Workflows"
>
<Grid
container
spacing={3}
>
<Grid
item
xs={12}
>
<Header listWorkflows={listWorkflows} />
</Grid>
{
!loading &&
<>
<Grid
item
xs={12}
>
<Search
config={{
title: "Workflows",
subject: "workflow",
data: Object.values(workflow.list.data),
filters: ["name", "description"],
}}
/>
</Grid>
<Grid
item
xs={12}
>
<WorkflowCard />
</Grid>
</>
}
{
loading &&
<ProgressSpinner message={'Loading Workflows...'} />
}
</Grid>
</Page>
);
};
export default WorkflowList;