> Portal Navigation:
> 
> - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version.
> - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages).
> - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`).
> - Top-level index of all portals: https://dev.wix.com/docs/llms.txt
> - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt

## Resource: Write Unit Tests for a Wix CLI Project

## Article: Write Unit Tests for a Wix CLI Project

## Article Link: https://dev.wix.com/docs/build-apps/develop-your-app/develop-an-app-with-the-cli/project-development/test-and-monitor/write-unit-tests-for-a-wix-cli-project.md

## Article Content:

# Write Unit Tests for a Wix CLI Project

This article explains how to write unit tests for a CLI project using [Vitest](https://vitest.dev/) and `@testing-library/react`.

> **Note:** While this article's flow uses Vitest specifically, the CLI is framework-agnostic and supports any testing library.

This article covers:

- Preparing your project for unit testing with Vitest.
- Writing unit tests for your project.

## Before you begin

+ You must have a project that was [created using the Wix CLI](https://dev.wix.com/docs/wix-cli/guides/about-the-wix-cli.md).
+ You must be logged into your Wix account. If you don't have one, [sign up for a Wix account](https://manage.wix.com/account/custom-apps).

## Step 1 | Configure your project for tests

1. Run the following command to install the required packages:  

   ```bash
   npm add vitest jsdom @testing-library/jest-dom @testing-library/user-event @testing-library/react@12 -D
   ```  

   > **Note**: Since the Wix CLI uses React 16 for dashboard extensions, we currently only support version 12 of `@testing-library/react`.

2. Create or update your `vitest.config.js` file with the following configuration:  

   ```javascript
   import { defineConfig } from 'vitest/config';
   
   export default defineConfig({
     test: {
       include: ['src/**/*.(test|spec).ts?(x)'],
       exclude: ['build', 'node_modules'],
       environment: 'jsdom',
       maxConcurrency: 7,
       setupFiles: './tests/setup.ts',
     },
   });
   ```  

3. Create a test setup file at `tests/setup.ts`. This file is used for general test configuration with Vitest:  

   ```javascript
   import { expect, afterEach } from 'vitest';
   import { cleanup } from '@testing-library/react';
   import * as matchers from '@testing-library/jest-dom/matchers';
   
   expect.extend(matchers);
   
   afterEach(() => {
     cleanup();
   });
   ```  

4. Add the following script to your `package.json` file to trigger unit tests:  

   ```json
   {
    "name": "your-wix-cli-project",
    "version": "1.0.0",
    "private": true,
    "scripts": {
        "wix": "wix",
        "test:unit": "vitest run"
        // ...
      },
    }
   ```  

## Step 2 | Write unit tests

Depending on your project's functionality, testing your project's react components may involve mocking Wix JavaScript SDK APIs, backend interactions, or both.

### Test a react component without the SDK or backend interactions

To test a react component like a dashboard page, check that aspects of the component would be rendered correctly.

For example, given the following dashboard page:

```javascript
import React, { type FC } from 'react';
import { EmptyState, Page } from '@wix/design-system';
import '@wix/design-system/styles.global.css';

const Index: FC = () => {
  return (
    <Page>
      <Page.Header title="Dashboard Page" />
      <Page.Content>
        <EmptyState
          title="Start editing this dashboard page!"
          theme="page"
        ></EmptyState>
      </Page.Content>
    </Page>
  );
};

export default Index;
```

You can test whether the "Dashboard Page" text would be present on the page when rendered.

```javascript
import React from 'react';
import { describe, expect, it } from 'vitest';
import { render } from '@testing-library/react';
import Page from './page';

describe('Index Page', () => {
  it('should render the page', async () => {
    const { findByText } = render(<Page />);

    await findByText('Dashboard Page');
  });
});
```

### Test a component that involves an SDK API call

If your component's code calls a Wix JavaScript SDK API, render the component and manually mock the API.

The following example demonstrates how to mock the Dashboard API's [`showToast()`](https://dev.wix.com/docs/sdk/host-modules/dashboard/show-toast.md) method.

```javascript
import React from 'react';
import { beforeEach, describe, expect, it, vi } from 'vitest';
import { render } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { dashboard } from '@wix/dashboard';
import Page from './page';

vi.mock('@wix/dashboard');

describe('Index Page', () => {
  beforeEach(() => {
    vi.clearAllMocks();
  });
  
  it('should show toast', async () => {
    const { findByText } = render(<Page />);
    const toastBtn = await findByText('Show a toast');
    await userEvent.click(toastBtn);
    expect(dashboard.showToast).toBeCalledWith({ message: 'Your first toast message' });
    expect(dashboard.showToast).toHaveBeenCalledOnce();
  });
});
```  

### Test a component that involves backend interactions

If your project interacts with a backend, mock those interactions using Vitest.

For example, if you have a page that calls the CRM backend to retrieve user contacts:

```javascript
import React, { useEffect, useState, type FC } from 'react';
import { contacts } from '@wix/crm';
import {
  Page,
  Card,
  Box,
  Loader,
  Text,
  Table,
  WixDesignSystemProvider,
} from '@wix/design-system';
import '@wix/design-system/styles.global.css';

const Index: FC = () => {
  const [userContacts, setUserContacts] = useState<contacts.Contact[]>();
  const [isLoading, setIsLoading] = useState<boolean>(true);
  const [err, setErr] = useState<Error | null>(null);

  useEffect(() => {
    const fetchContacts = async () => {
      try {
        const result = await contacts.queryContacts({});
        setUserContacts(result.items);
      } catch (queryError) {
        setErr(queryError);
      } finally {
        setIsLoading(false);
      }
    };

    fetchContacts();
  }, []);

  return (
    <WixDesignSystemProvider features={{ newColorsBranding: true }}>
      <Page>
        <Page.Content>
          <Card>
            <Card.Content>
              {isLoading && (
                <Box align="center">
                  <Loader text="Loading contacts..." />
                </Box>
              )}
              {err && <Text>Error: {err.message}</Text>}
              {(userContacts?.length || 0) > 0 && (
                <Table
                  data={userContacts}
                  columns={[
                    { title: 'ID', render: (row) => row._id },
                    {
                      title: 'First Name',
                      render: (row) => row.info?.name?.first,
                    },
                    {
                      title: 'Last Name',
                      render: (row) => row.info?.name?.last,
                    },
                  ]}
                />
              )}
            </Card.Content>
          </Card>
        </Page.Content>
      </Page>
    </WixDesignSystemProvider>
  );
};

export default Index;
```

You would mock the backend interactions with the API using `vitest` as follows:

```javascript
import React from 'react';
import { randomUUID } from 'node:crypto';
import { describe, expect, it, vi } from 'vitest';
import { render } from '@testing-library/react';
import Page from './page';

vi.mock('@wix/crm', () => ({
  contacts: {
    queryContacts: async () => ({
      items: [
        {
          _id: randomUUID(),
          info: {
            name: {
              first: 'John',
              last: 'Doe'
            },
          },
        }
      ],
    }),
  },
}));

describe('test page', () => {
  it('should display contact', async () => {
    const { findByText } = render(<Page />);

    const firstNameEl = await findByText('John');
    expect(firstNameEl).toBeDefined();

    const lastNameEl = await findByText('Doe');
    expect(lastNameEl).toBeDefined();
  });
});
```

## See also

- [Integrate the Wix CLI into CI/CD Workflows](https://dev.wix.com/docs/build-apps/develop-your-app/frameworks/wix-cli/project-development/cd-workflows.md)