Files

3.3 KiB

Vitest Setup and Migration Guide

Vitest vs Jasmine Comparison

Feature Vitest Jasmine/Karma
Speed Faster (native ESM) Slower
Watch mode Instant feedback Slower rebuilds
Mocking vi.fn(), vi.mock() jasmine.createSpy()
Assertions expect() (Chai-style) expect() (Jasmine)
UI Built-in UI mode Karma browser
Config angular.json karma.conf.js

Migration from Jasmine to Vitest

Spy Migration

// Jasmine
const spy = jasmine.createSpy('callback');
spy.and.returnValue('value');
expect(spy).toHaveBeenCalledWith('arg');

// Vitest
const spy = vi.fn();
spy.mockReturnValue('value');
expect(spy).toHaveBeenCalledWith('arg');

SpyOn Migration

// Jasmine
spyOn(service, 'method').and.returnValue(of(data));

// Vitest
vi.spyOn(service, 'method').mockReturnValue(of(data));

createSpyObj Migration

// Jasmine
const mockService = jasmine.createSpyObj('UserService', ['getUser', 'updateUser']);
mockService.getUser.and.returnValue(of({ id: '1', name: 'Test' }));

// Vitest
const mockService = {
    getUser: vi.fn(),
    updateUser: vi.fn(),
};
mockService.getUser.mockReturnValue(of({ id: '1', name: 'Test' }));

Async Testing Migration

// Jasmine - using done callback
it('should load data', (done) => {
    service.loadData().subscribe((data) => {
        expect(data).toBeDefined();
        done();
    });
});

// Vitest - using async/await
it('should load data', async () => {
    const data = await firstValueFrom(service.loadData());
    expect(data).toBeDefined();
});

Clock/Timer Migration

// Jasmine
jasmine.clock().install();
jasmine.clock().tick(1000);
jasmine.clock().uninstall();

// Vitest
vi.useFakeTimers();
vi.advanceTimersByTime(1000);
vi.useRealTimers();

Vitest Configuration Details

Full angular.json Configuration

{
    "projects": {
        "your-app": {
            "architect": {
                "test": {
                    "builder": "@angular/build:unit-test",
                    "options": {
                        "tsConfig": "tsconfig.spec.json",
                        "buildTarget": "your-app:build"
                    }
                }
            }
        }
    }
}

tsconfig.spec.json

{
    "extends": "./tsconfig.json",
    "compilerOptions": {
        "types": ["vitest/globals"]
    },
    "include": ["src/**/*.spec.ts"]
}

Optional vite.config.ts

For advanced configuration, create a vite.config.ts:

import { defineConfig } from 'vitest/config';

export default defineConfig({
    test: {
        globals: true,
        environment: 'jsdom',
        include: ['src/**/*.spec.ts'],
        coverage: {
            provider: 'v8',
            reporter: ['text', 'html', 'lcov'],
            exclude: ['node_modules/', 'src/test-setup.ts', '**/*.spec.ts', '**/*.d.ts'],
        },
    },
});

Running Vitest

# Run tests
ng test

# Watch mode
ng test --watch

# Coverage
ng test --code-coverage

# Run specific file pattern
ng test --include='**/user*.spec.ts'

# CI mode (single run)
ng test --watch=false