jest-generator

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Jest Generator Skill

Jest测试生成Skill

Purpose

用途

Generate Jest-based unit tests for JavaScript and TypeScript code, following Jest conventions and best practices with proper mocking, describe blocks, and code organization.
为JavaScript和TypeScript代码生成基于Jest的单元测试,遵循Jest的规范和最佳实践,包含正确的Mock、describe代码块及代码组织结构。

When to Use

适用场景

  • Generate Jest tests for JavaScript/TypeScript modules
  • Create test files for React components
  • Add missing test coverage to existing code
  • Need Jest-specific patterns (mocks, spies, snapshots)
  • 为JavaScript/TypeScript模块生成Jest测试
  • 为React组件创建测试文件
  • 为现有代码补充缺失的测试覆盖率
  • 需要使用Jest特定模式(Mock、Spy、快照)

Test File Naming

测试文件命名规范

Source to Test Mapping:
  • src/components/Feature.tsx
    src/components/Feature.test.tsx
  • src/utils/validator.ts
    src/utils/validator.test.ts
  • src/models/User.ts
    src/models/User.test.ts
源码与测试文件映射:
  • src/components/Feature.tsx
    src/components/Feature.test.tsx
  • src/utils/validator.ts
    src/utils/validator.test.ts
  • src/models/User.ts
    src/models/User.test.ts

Running Tests

运行测试

bash
undefined
bash
undefined

Preferred: Using bun (faster)

推荐:使用bun(速度更快)

bun test
bun test

Run specific file

运行指定文件

bun test src/utils/validator.test.ts
bun test src/utils/validator.test.ts

Run with coverage

带覆盖率统计运行

bun test --coverage
bun test --coverage

Watch mode

监听模式

bun test --watch
bun test --watch

Alternative: Using npm

替代方案:使用npm

npm test npm test -- --coverage
undefined
npm test npm test -- --coverage
undefined

Jest Test Structure

Jest测试结构

typescript
import { functionToTest, ClassToTest } from './Feature'

jest.mock('./dependency')

describe('ModuleName', () => {
  beforeEach(() => {
    jest.clearAllMocks()
  })

  afterEach(() => {
    jest.restoreAllMocks()
  })

  describe('ClassName', () => {
    let instance: ClassToTest

    beforeEach(() => {
      instance = new ClassToTest()
    })

    it('should return expected result with valid input', () => {
      // Arrange
      const input = { key: 'value' }
      const expected = { processed: true }

      // Act
      const result = instance.method(input)

      // Assert
      expect(result).toEqual(expected)
    })

    it('should throw error with invalid input', () => {
      expect(() => instance.method(null)).toThrow('Invalid input')
    })
  })
})
typescript
import { functionToTest, ClassToTest } from './Feature'

jest.mock('./dependency')

describe('ModuleName', () => {
  beforeEach(() => {
    jest.clearAllMocks()
  })

  afterEach(() => {
    jest.restoreAllMocks()
  })

  describe('ClassName', () => {
    let instance: ClassToTest

    beforeEach(() => {
      instance = new ClassToTest()
    })

    it('should return expected result with valid input', () => {
      // Arrange
      const input = { key: 'value' }
      const expected = { processed: true }

      // Act
      const result = instance.method(input)

      // Assert
      expect(result).toEqual(expected)
    })

    it('should throw error with invalid input', () => {
      expect(() => instance.method(null)).toThrow('Invalid input')
    })
  })
})

Jest-Specific Patterns

Jest特定模式

Mocking

Mocking(模拟)

typescript
// Mock entire module
jest.mock('./api', () => ({
  fetchData: jest.fn(),
}))

// Mock with implementation
const mockFn = jest.fn((x: number) => x * 2)

// Spy on method
const spy = jest.spyOn(obj, 'method').mockReturnValue('mocked')
spy.mockRestore()
typescript
// 模拟整个模块
jest.mock('./api', () => ({
  fetchData: jest.fn(),
}))

// 带实现逻辑的模拟
const mockFn = jest.fn((x: number) => x * 2)

// 监视方法
const spy = jest.spyOn(obj, 'method').mockReturnValue('mocked')
spy.mockRestore()

Async Testing

异步测试

typescript
it('should resolve with data', async () => {
  const result = await asyncFunction()
  expect(result).toBeDefined()
})

it('should reject with error', async () => {
  await expect(asyncFunction()).rejects.toThrow('Error')
})
typescript
it('should resolve with data', async () => {
  const result = await asyncFunction()
  expect(result).toBeDefined()
})

it('should reject with error', async () => {
  await expect(asyncFunction()).rejects.toThrow('Error')
})

Timers

定时器测试

typescript
beforeEach(() => jest.useFakeTimers())
afterEach(() => jest.useRealTimers())

it('should execute after timeout', () => {
  const callback = jest.fn()
  setTimeout(callback, 1000)
  jest.advanceTimersByTime(1000)
  expect(callback).toHaveBeenCalled()
})
typescript
beforeEach(() => jest.useFakeTimers())
afterEach(() => jest.useRealTimers())

it('should execute after timeout', () => {
  const callback = jest.fn()
  setTimeout(callback, 1000)
  jest.advanceTimersByTime(1000)
  expect(callback).toHaveBeenCalled()
})

Common Matchers

常用匹配器

typescript
// Equality
expect(value).toBe(expected)
expect(value).toEqual(expected)

// Truthiness
expect(value).toBeTruthy()
expect(value).toBeNull()
expect(value).toBeDefined()

// Arrays/Objects
expect(array).toContain(item)
expect(obj).toHaveProperty('key')

// Functions/Promises
expect(fn).toThrow('error')
await expect(promise).resolves.toBe(value)

// Mock functions
expect(mockFn).toHaveBeenCalled()
expect(mockFn).toHaveBeenCalledWith(arg)
typescript
// 相等性
expect(value).toBe(expected)
expect(value).toEqual(expected)

// 真值判断
expect(value).toBeTruthy()
expect(value).toBeNull()
expect(value).toBeDefined()

// 数组/对象
expect(array).toContain(item)
expect(obj).toHaveProperty('key')

// 函数/Promise
expect(fn).toThrow('error')
await expect(promise).resolves.toBe(value)

// 模拟函数
expect(mockFn).toHaveBeenCalled()
expect(mockFn).toHaveBeenCalledWith(arg)

React Component Testing

React组件测试

typescript
import { render, screen, fireEvent } from '@testing-library/react'
import '@testing-library/jest-dom'
import { Button } from './Button'

describe('Button', () => {
  it('should call onClick when clicked', () => {
    const handleClick = jest.fn()
    render(<Button onClick={handleClick}>Click me</Button>)
    fireEvent.click(screen.getByText('Click me'))
    expect(handleClick).toHaveBeenCalledTimes(1)
  })
})
typescript
import { render, screen, fireEvent } from '@testing-library/react'
import '@testing-library/jest-dom'
import { Button } from './Button'

describe('Button', () => {
  it('should call onClick when clicked', () => {
    const handleClick = jest.fn()
    render(<Button onClick={handleClick}>Click me</Button>)
    fireEvent.click(screen.getByText('Click me'))
    expect(handleClick).toHaveBeenCalledTimes(1)
  })
})

Quality Checklist

质量检查清单

  • Test file properly named (
    <module>.test.ts
    )
  • All exported functions/classes tested
  • Happy path and edge cases included
  • Error conditions tested
  • External dependencies mocked
  • Tests organized with describe blocks
  • beforeEach/afterEach for setup/cleanup
  • Descriptive test names
  • Coverage ≥ 80%
  • 测试文件命名规范(
    <module>.test.ts
  • 所有导出的函数/类均已测试
  • 包含正常流程和边缘场景测试
  • 测试了错误情况
  • 外部依赖已被Mock
  • 测试用describe块组织
  • 使用beforeEach/afterEach进行初始化/清理
  • 测试名称具有描述性
  • 覆盖率≥80%

Best Practices

最佳实践

  1. Use descriptive test names:
    should <expected> when <condition>
  2. Organize with describe blocks
  3. Mock external dependencies only
  4. Test user behavior for components
  5. Use test.each for parametrized tests
  6. Keep tests independent
  7. Test error conditions
  8. Aim for 80%+ coverage
  1. 使用具有描述性的测试名称:
    should <预期结果> when <条件>
  2. 用describe块组织测试
  3. 仅Mock外部依赖
  4. 针对组件测试用户行为
  5. 使用test.each进行参数化测试
  6. 保持测试独立性
  7. 测试错误条件
  8. 目标覆盖率≥80%