`UserEvent` doesn't fire on 1 element from getAll* in vitest & testing-library/react

14 Views Asked by At

I'm trying to test the notifications component. When the user clicks on one of the cards it should call method markNotificationAsRead but when I write the test like this:

it('should mark notification as read and navigate to correct page when clicked', async () => {
    vi.mock('../services/notifications.http', () => ({
        markNotificationAsRead: vi.fn(),
        markAllNotificationsAsRead: vi.fn(),
        loadNotifications: vi.fn(),
    }));
    vi.mock('@tanstack/react-query', async () => {
        const mod = await vi.importActual<typeof import('@tanstack/react-query')>('@tanstack/react-query');
        return {
            ...mod,
            useInfiniteQuery: vi.fn(() => ({
                data: {
                    pages: [
                        [
                            {
                                id: '1',
                                text: 'Notification 1',
                                title: 'Title 1',
                                data: {
                                    id: 1,
                                    notify_type: 'type1',
                                    category: 'category1',
                                },
                                read: false,
                                type: 'type1',
                                created_at: '2022-01-01T00:00:00Z',
                            },
                        ],
                        [
                            {
                                id: '2',
                                text: 'Notification 2',
                                title: 'Title 2',
                                data: {
                                    id: 2,
                                    notify_type: 'type2',
                                    category: 'category2',
                                },
                                read: true,
                                type: 'type2',
                                created_at: '2022-01-02T00:00:00Z',
                            },
                        ],
                    ],
                },
                fetchNextPage: vi.fn(),
                hasNextPage: true,
                isFetching: false,
                isLoading: false,
            })),
            useQueryClient: vi.fn(() => ({
                invalidateQueries: vi.fn(),
            })),
        };
    });
    const markNotificationAsRead = vi.spyOn(notificationsHttp, 'markNotificationAsRead');
    renderWithProviders(<Notifications />);
    const firstNotificationCard = screen.getAllByRole('listitem', { name: 'Notification' })[0];

    await userEvent.click(firstNotificationCard);

    await waitFor(() => {
        expect(markNotificationAsRead).toHaveBeenCalled();
    });
});

When i run this test i get: AssertionError: expected "spy" to be called at least once

I tried to put the click in a act function and tried fireEvent, and none of them worked for me. Also, I'm sure that the card functions normally when clicking on it in normal ui.

Here's the exact same test but it tests the mark All as read functionality and is working normally

it('should mark all notifications as read when "Mark all as read" button is clicked', async () => {
    const markAllNotificationsAsRead = vi.spyOn(notificationsHttp, 'markAllNotificationsAsRead');
    renderWithProviders(<Notifications />);
    const allReadBtn = await waitFor(() => screen.getByRole('button', { name: 'allUnread' }));

    userEvent.click(allReadBtn);

    await waitFor(() => {
        expect(markAllNotificationsAsRead).toHaveBeenCalled();
    });
});

The 2 tests are the same, except that the 1st test fires click on item from a list and the second fires click on a single btn.

0

There are 0 best solutions below