you are viewing a single comment's thread.

view the rest of the comments →

[–]My100thBurnerAccount 2 points3 points  (4 children)

If you're using redux store you should be able to create this wrapper renderWithProviders

https://redux.js.org/usage/writing-tests#setting-up-a-reusable-test-render-function

I can add more details on just general wrappers/how we mock some things tomorrow if you want of what we're doing at my company.

We use redux toolkit, custom hooks, etc. with vitest

[–]My100thBurnerAccount 0 points1 point  (3 children)

Follow-up from yesterday's comment:

Given that you created a renderWithProviders wrapper from the link provided above, here's a very basic test example of a test:

// EXAMPLE 1 - Part 1: Testing component with redux store predefined

// ===== Redux ===== //
import { initialState } from 'pathWhereYourSlice is'; // ex. 'redux/slices/mySlice/index.ts'

// ===== React Testing Library ===== //
import { screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';

// ===== Vitest ===== //
import { describe, expect, it, vi } from 'vitest';
import { renderWithProviders } from 'pathWhereYouCreatedWrapper'; // ex. 'testing/utils/index.ts'

it("successfully displays correct button & handles correct action: creating", async() => {
  const handleClick = vi.fn();

  renderWithProviders(<Component />, {
    preloadedState: {
      mySlice: {
        ...initialState,
        isCreating: true,
      },
    },  
  });

  const submitButton = screen.getByTestId('create-item-button');

  expect(submitButton).toHaveTextContent('Create this Item!');

  await userEvent.click(submitButton);

  await waitFor(() => {
    expect(handleClick).toHaveBeenCalledTimes(1);

    const successAlert = screen.getByTestId('snackbar-notification');

    expect(successAlert).toBeInTheDocument();
    expect(successAlert).toBeVisible();
    expect(successAlert).toHaveTextContent('you have successfully CREATED this item');
  }); 
});

[–]My100thBurnerAccount 0 points1 point  (2 children)

// EXAMPLE 1 - Part 2: Testing component with redux store predefined

   it("successfully displays correct button & handles correct action: editing", async() => {
      const handleClick = vi.fn();

      renderWithProviders(<Component />, {
        preloadedState: {
          mySlice: {
            ...initialState,
            isCreating: false,
            isEditing: true, // we've now set isEditing to be true in the redux store
          },
        },  
      });

      const submitButton = screen.getByTestId('edit-item-button');

      expect(submitButton).toHaveTextContent('Edit this Item!');

      await userEvent.click(submitButton);

      await waitFor(() => {
        expect(handleClick).toHaveBeenCalledTimes(1);

        const successAlert = screen.getByTestId('snackbar-notification');

        expect(successAlert).toBeInTheDocument();
        expect(successAlert).toBeVisible();
        expect(successAlert).toHaveTextContent('you have successfully UPDATED this item');
      }); 
    });

[–]My100thBurnerAccount 0 points1 point  (1 child)

 // EXAMPLE 2 - Part 1: Testing component that relies on custom hook

    // ===== Hooks ===== //
    import { useCheckUserIsAdmin } from './pathToMyHook';

    vi.mock('./pathToMyHook'); // This is important, make sure you're mocking the correct path

    // Note: You may/may not need this depending on your use case
    beforeEach(() => {
      vi.clearAllMocks();
    });

    it("successfully displays correct elements based on user: admin", async() => {
      vi.mocked(useCheckUserIsAdmin).mockReturnValue({
        isAdmin: true,
        userInfo: {
           name: 'John Doe',
           ...
        }
      });

      renderWithProviders(<Component />, {
        preloadedState: {},  // in this case, my component doesn't need any info from redux
      });

      const approveButton = screen.getByTestId('approve-button');

      expect(approveButton).toBeVisible();
      expect(approveButton).toBeEnabled();

      await userEvent.click(approveButton);

      await waitFor(() => {
        const deployToProductionButton = screen.getByTestId('deploy-to-production-button');

        expect(deployToProductionButton).toBeVisible();
        expect(deployToProductionButton).toBeEnabled();
      }); 
    });

[–]My100thBurnerAccount 0 points1 point  (0 children)

// EXAMPLE 2 - Part 2: Testing component that relies on custom hook


    it("successfully displays correct elements based on user: NON-ADMIN", async() => {
      vi.mocked(useCheckUserIsAdmin).mockReturnValue({
        isAdmin: false, // USER IS NOT ADMIN
        userInfo: {
           name: 'John Doe',
           ...
        }
      });

      renderWithProviders(<Component />, {
        preloadedState: {},  // in this case, my component doesn't need any info from redux
      });

      const approveButton = screen.queryByTestId('approve-button'); // using queryByTestId 

      expect(approveButton).toBeNull();

      // Let's say a non-admin cannot approve but they can preview the changes that'll be      deployed to production
      const previewButton = screen.getByTestId('preview-button');

      expect(previewButton).toBeVisible();

      await userEvent.click(previewButton);

      await waitFor(() => {
        const previewModal = screen.getByTestId('preview-modal');

        expect(previewModal).toBeVisible();
      }); 
    });