GAZAR

Principal Engineer | Mentor

Using Vitest, MSW, and Faker in TypeScript

Using Vitest, MSW, and Faker in TypeScript

If you’re working with Vite, then you’ll love Vitest. It’s a test runner that integrates seamlessly with Vite projects and has a Jest-like API, so it’s easy to pick up if you’re familiar with Jest.

Next, tweak your vite.config.ts to set up Vitest:

import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  test: {
    globals: true,
    environment: 'jsdom',
  },
});

and

import { describe, it, expect } from 'vitest';

describe('sum function', () => {
  it('should return the correct sum', () => {
    const sum = (a: number, b: number) => a + b;
    expect(sum(1, 2)).toBe(3);
  });
});

Mocking API calls is essential, and MSW is perfect for this. It intercepts network requests at the service worker level, providing a way to mock APIs for both testing and development.

Create a src/mocks/handlers.ts to define your request handlers:

import { rest } from 'msw';
export const handlers = [
  rest.get('/api/user', (req, res, ctx) => {
    return res(
      ctx.status(200),
      ctx.json({ id: 'abc-123', firstName: 'John', lastName: 'Doe' })
    );
  }),
];

Initialize the service worker in src/mocks/browser.ts:

import { setupWorker } from 'msw';
import { handlers } from './handlers';

export const worker = setupWorker(...handlers);

In your src/index.tsx, start the service worker during test:

if (process.env.NODE_ENV === 'test') {
  const { worker } = require('./mocks/browser');
  worker.start();
}

Set up MSW in your test environment (e.g., setupTests.ts):

import { setupServer } from 'msw/node';
import { handlers } from './mocks/handlers';

const server = setupServer(...handlers);

beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

Now you can write tests that rely on mocked API responses:

import { render, screen } from '@testing-library/react';
import App from './App';
test('renders user data', async () => {
  render(<App />);
  const userData = await screen.findByText(/John Doe/i);
  expect(userData).toBeInTheDocument();
});

When you need realistic fake data, Faker is your friend. It helps create random data for testing, which can make your tests more robust.

import { faker } from '@faker-js/faker';

test('generate random user', () => {
  const user = {
    id: faker.datatype.uuid(),
    firstName: faker.name.firstName(),
    lastName: faker.name.lastName(),
  };
  expect(user).toHaveProperty('id');
  expect(user).toHaveProperty('firstName');
  expect(user).toHaveProperty('lastName');
});

Running tests from the command line is fine, but Vitest UI gives you a visual interface that makes it easier to run and debug tests.

npm install @vitest/ui --save-dev

And

npx vitest --ui

Vitest VSCode: Integrating with Visual Studio Code

Setting Up Vitest in VSCode

  • Install the VSCode Extension: Search for and install the "Vitest" extension from the VSCode marketplace.
  • Configure the Extension: Add the following to your .vscode/settings.json to ensure the extension works correctly:
{
  "vitest.enable": true,
  "vitest.configFile": "vite.config.ts"
}

Integrating Vitest, MSW, Faker, and Vitest UI into your TypeScript projects can greatly enhance your testing workflow. These tools provide everything you need to write, run, and manage tests, ensuring your code remains robust and maintainable. Plus, with the Vitest VSCode extension, you can streamline your workflow even further. Give these tools a try and see how they can improve your development process!