mock-generator by dexploarer/claudius-skills
npx skills add https://github.com/dexploarer/claudius-skills --skill mock-generator自动为各种测试框架生成测试模拟对象、桩和夹具。
询问用户或分析代码以确定:
扫描测试框架:
# 检查 package.json 中的测试框架
grep -E "(jest|vitest|mocha|jasmine|pytest|unittest|minitest)" package.json
# 查找测试文件
find . -name "*.test.*" -o -name "*.spec.*" -o -name "test_*.py"
函数模拟:
API 模拟:
类模拟:
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
模块模拟:
简单函数模拟:
// Mock a simple function
const mockFn = jest.fn()
mockFn.mockReturnValue(42)
// Use in test
test('uses mocked function', () => {
expect(mockFn()).toBe(42)
expect(mockFn).toHaveBeenCalled()
})
具有不同返回值的函数:
const mockFn = jest.fn()
.mockReturnValueOnce('first')
.mockReturnValueOnce('second')
.mockReturnValue('default')
expect(mockFn()).toBe('first')
expect(mockFn()).toBe('second')
expect(mockFn()).toBe('default')
模拟实现:
const mockFn = jest.fn((x, y) => x + y)
expect(mockFn(1, 2)).toBe(3)
expect(mockFn).toHaveBeenCalledWith(1, 2)
模块模拟:
// __mocks__/axios.js
export default {
get: jest.fn(() => Promise.resolve({ data: {} })),
post: jest.fn(() => Promise.resolve({ data: {} })),
}
// In test file
jest.mock('axios')
import axios from 'axios'
test('fetches data', async () => {
axios.get.mockResolvedValue({ data: { name: 'John' } })
const result = await fetchUser(1)
expect(result.name).toBe('John')
expect(axios.get).toHaveBeenCalledWith('/users/1')
})
类模拟:
// Mock a class
jest.mock('./Database')
import Database from './Database'
Database.mockImplementation(() => ({
query: jest.fn().mockResolvedValue([{ id: 1, name: 'John' }]),
connect: jest.fn().mockResolvedValue(true),
disconnect: jest.fn().mockResolvedValue(true),
}))
test('uses database', async () => {
const db = new Database()
const users = await db.query('SELECT * FROM users')
expect(users).toHaveLength(1)
expect(db.query).toHaveBeenCalled()
})
部分模拟:
// Mock only specific methods
import * as utils from './utils'
jest.spyOn(utils, 'fetchData').mockResolvedValue({ data: 'mocked' })
test('uses mocked method', async () => {
const result = await utils.fetchData()
expect(result.data).toBe('mocked')
})
函数模拟:
import { vi, expect, test } from 'vitest'
const mockFn = vi.fn()
mockFn.mockReturnValue(42)
test('uses mock', () => {
expect(mockFn()).toBe(42)
})
模块模拟:
// __mocks__/api.ts
import { vi } from 'vitest'
export const fetchUser = vi.fn()
export const createUser = vi.fn()
// In test
vi.mock('./api')
import { fetchUser } from './api'
test('fetches user', async () => {
fetchUser.mockResolvedValue({ id: 1, name: 'John' })
const user = await fetchUser(1)
expect(user.name).toBe('John')
})
监视方法:
import { vi } from 'vitest'
const obj = {
method: () => 'original'
}
vi.spyOn(obj, 'method').mockReturnValue('mocked')
expect(obj.method()).toBe('mocked')
类型安全模拟:
import { vi } from 'vitest'
interface User {
id: number
name: string
email: string
}
// Create type-safe mock
const mockUser: User = {
id: 1,
name: 'John Doe',
email: 'john@example.com'
}
// Mock function with types
const mockFetchUser = vi.fn<[id: number], Promise<User>>()
mockFetchUser.mockResolvedValue(mockUser)
模拟工厂:
// Create a factory for generating mocks
function createMockUser(overrides?: Partial<User>): User {
return {
id: 1,
name: 'Test User',
email: 'test@example.com',
...overrides
}
}
// Use in tests
const user1 = createMockUser({ name: 'Alice' })
const user2 = createMockUser({ id: 2, email: 'bob@example.com' })
函数模拟:
from unittest.mock import Mock
# Simple mock
mock_func = Mock(return_value=42)
assert mock_func() == 42
assert mock_func.called
# Mock with side effects
mock_func = Mock(side_effect=[1, 2, 3])
assert mock_func() == 1
assert mock_func() == 2
assert mock_func() == 3
Patch 装饰器:
from unittest.mock import patch, Mock
@patch('requests.get')
def test_fetch_data(mock_get):
# Setup mock
mock_response = Mock()
mock_response.json.return_value = {'name': 'John'}
mock_response.status_code = 200
mock_get.return_value = mock_response
# Test
result = fetch_user_data(1)
assert result['name'] == 'John'
mock_get.assert_called_once_with('https://api.example.com/users/1')
类模拟:
from unittest.mock import Mock, patch
@patch('database.Database')
def test_database_query(mock_database_class):
# Setup mock instance
mock_db = Mock()
mock_db.query.return_value = [{'id': 1, 'name': 'John'}]
mock_database_class.return_value = mock_db
# Test
db = Database()
users = db.query('SELECT * FROM users')
assert len(users) == 1
assert users[0]['name'] == 'John'
mock_db.query.assert_called_once()
上下文管理器模拟:
from unittest.mock import patch, mock_open
# Mock file operations
mock_data = "file contents"
with patch('builtins.open', mock_open(read_data=mock_data)):
with open('file.txt') as f:
content = f.read()
assert content == mock_data
简单夹具:
import pytest
@pytest.fixture
def mock_user():
return {
'id': 1,
'name': 'John Doe',
'email': 'john@example.com'
}
def test_user_data(mock_user):
assert mock_user['name'] == 'John Doe'
带清理的夹具:
@pytest.fixture
def mock_database():
# Setup
db = MockDatabase()
db.connect()
yield db # Provide to test
# Teardown
db.disconnect()
def test_database_query(mock_database):
result = mock_database.query('SELECT * FROM users')
assert len(result) > 0
参数化夹具:
@pytest.fixture(params=[
{'name': 'Alice', 'age': 25},
{'name': 'Bob', 'age': 30},
{'name': 'Charlie', 'age': 35}
])
def mock_user(request):
return request.param
def test_user_age(mock_user):
assert mock_user['age'] > 0
def test_api_call(mocker):
# Mock a function
mock_get = mocker.patch('requests.get')
mock_get.return_value.json.return_value = {'status': 'ok'}
result = fetch_data()
assert result['status'] == 'ok'
mock_get.assert_called_once()
// Mock fetch API
global.fetch = jest.fn(() =>
Promise.resolve({
ok: true,
status: 200,
json: async () => ({
id: 1,
name: 'John Doe',
email: 'john@example.com'
}),
headers: new Headers({
'Content-Type': 'application/json'
})
})
)
test('fetches user', async () => {
const user = await fetchUser(1)
expect(user.name).toBe('John Doe')
expect(fetch).toHaveBeenCalledWith('/api/users/1')
})
// mocks/handlers.js
import { rest } from 'msw'
export const handlers = [
rest.get('/api/users/:id', (req, res, ctx) => {
const { id } = req.params
return res(
ctx.status(200),
ctx.json({
id: Number(id),
name: 'John Doe',
email: 'john@example.com'
})
)
}),
rest.post('/api/users', (req, res, ctx) => {
return res(
ctx.status(201),
ctx.json({
id: 123,
...req.body
})
)
}),
rest.get('/api/users', (req, res, ctx) => {
return res(
ctx.status(200),
ctx.json([
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
])
)
})
]
// mocks/server.js
import { setupServer } from 'msw/node'
import { handlers } from './handlers'
export const server = setupServer(...handlers)
// setupTests.js
import { server } from './mocks/server'
beforeAll(() => server.listen())
afterEach(() => server.resetHandlers())
afterAll(() => server.close())
import { graphql } from 'msw'
export const handlers = [
graphql.query('GetUser', (req, res, ctx) => {
const { id } = req.variables
return res(
ctx.data({
user: {
id,
name: 'John Doe',
email: 'john@example.com'
}
})
)
}),
graphql.mutation('CreateUser', (req, res, ctx) => {
const { input } = req.variables
return res(
ctx.data({
createUser: {
id: '123',
...input
}
})
)
})
]
import { PrismaClient } from '@prisma/client'
import { mockDeep, mockReset, DeepMockProxy } from 'jest-mock-extended'
export const prismaMock = mockDeep<PrismaClient>()
beforeEach(() => {
mockReset(prismaMock)
})
// In test
test('creates user', async () => {
const mockUser = { id: 1, name: 'John', email: 'john@example.com' }
prismaMock.user.create.mockResolvedValue(mockUser)
const user = await createUser({ name: 'John', email: 'john@example.com' })
expect(user).toEqual(mockUser)
expect(prismaMock.user.create).toHaveBeenCalledWith({
data: { name: 'John', email: 'john@example.com' }
})
})
import { MongoMemoryServer } from 'mongodb-memory-server'
import { MongoClient } from 'mongodb'
let mongod
let client
let db
beforeAll(async () => {
mongod = await MongoMemoryServer.create()
const uri = mongod.getUri()
client = new MongoClient(uri)
await client.connect()
db = client.db()
})
afterAll(async () => {
await client.close()
await mongod.stop()
})
test('inserts user', async () => {
const users = db.collection('users')
const user = { name: 'John', email: 'john@example.com' }
await users.insertOne(user)
const found = await users.findOne({ name: 'John' })
expect(found.email).toBe('john@example.com')
})
import { render, screen } from '@testing-library/react'
import '@testing-library/jest-dom'
// Mock child component
jest.mock('./UserAvatar', () => ({
UserAvatar: ({ name }) => <div data-testid="avatar">{name}</div>
}))
test('renders user profile', () => {
render(<UserProfile name="John" />)
expect(screen.getByTestId('avatar')).toHaveTextContent('John')
})
import { renderHook } from '@testing-library/react'
// Mock useState
const mockSetState = jest.fn()
jest.spyOn(React, 'useState').mockImplementation(initial => [initial, mockSetState])
// Mock custom hook
jest.mock('./useUser')
import { useUser } from './useUser'
test('uses user hook', () => {
useUser.mockReturnValue({
user: { id: 1, name: 'John' },
loading: false,
error: null
})
const { result } = renderHook(() => useUser(1))
expect(result.current.user.name).toBe('John')
})
// fixtures/users.js
export const mockUsers = [
{ id: 1, name: 'Alice', email: 'alice@example.com', role: 'admin' },
{ id: 2, name: 'Bob', email: 'bob@example.com', role: 'user' },
{ id: 3, name: 'Charlie', email: 'charlie@example.com', role: 'user' }
]
export const mockUser = mockUsers[0]
// In tests
import { mockUser, mockUsers } from './fixtures/users'
test('processes user', () => {
const result = processUser(mockUser)
expect(result.name).toBe('Alice')
})
// factories/userFactory.js
let userId = 1
export function createUser(overrides = {}) {
return {
id: userId++,
name: 'Test User',
email: `user${userId}@example.com`,
role: 'user',
createdAt: new Date(),
...overrides
}
}
export function createAdmin(overrides = {}) {
return createUser({
role: 'admin',
...overrides
})
}
// In tests
import { createUser, createAdmin } from './factories/userFactory'
test('creates user', () => {
const user = createUser({ name: 'Alice' })
expect(user.name).toBe('Alice')
expect(user.role).toBe('user')
})
test('creates admin', () => {
const admin = createAdmin({ name: 'Bob' })
expect(admin.role).toBe('admin')
})
import factory
from myapp.models import User
class UserFactory(factory.Factory):
class Meta:
model = User
id = factory.Sequence(lambda n: n)
name = factory.Faker('name')
email = factory.Faker('email')
role = 'user'
# In tests
def test_user_creation():
user = UserFactory()
assert user.name is not None
assert '@' in user.email
def test_admin_creation():
admin = UserFactory(role='admin')
assert admin.role == 'admin'
// ❌ BAD: Overly complex mock
const mock = jest.fn()
mock.mockImplementation((a, b, c) => {
if (a > 10) {
return b * c
} else if (a < 5) {
return b + c
}
return a + b + c
})
// ✅ GOOD: Simple, focused mock
const mock = jest.fn().mockReturnValue(42)
// ✅ GOOD: Reusable factory
function createMockUser(overrides) {
return {
id: 1,
name: 'Test User',
email: 'test@example.com',
...overrides
}
}
afterEach(() => {
jest.clearAllMocks() // Clear call history
jest.resetAllMocks() // Clear call history + implementation
})
import { vi } from 'vitest'
const mockFn = vi.fn<[id: number], Promise<User>>()
// TypeScript ensures correct usage
mockFn(123) // ✅ OK
mockFn('abc') // ❌ TypeScript error
// Document why mock behaves this way
test('handles rate limiting', async () => {
// Mock returns 429 to simulate rate limiting
fetch.mockRejectedValueOnce(new Error('Rate limited'))
await expect(fetchData()).rejects.toThrow('Rate limited')
})
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation()
test('logs error', () => {
functionThatLogs()
expect(consoleErrorSpy).toHaveBeenCalledWith('Error occurred')
})
consoleErrorSpy.mockRestore()
jest.useFakeTimers()
test('delays execution', () => {
const callback = jest.fn()
setTimeout(callback, 1000)
jest.advanceTimersByTime(500)
expect(callback).not.toHaveBeenCalled()
jest.advanceTimersByTime(500)
expect(callback).toHaveBeenCalled()
})
jest.useRealTimers()
const mockDate = new Date('2024-01-01')
jest.spyOn(global, 'Date').mockImplementation(() => mockDate)
test('uses fixed date', () => {
const result = getCurrentDate()
expect(result.getFullYear()).toBe(2024)
})
每周安装量
1
代码仓库
GitHub 星标数
4
首次出现
1 天前
安全审计
已安装于
zencoder1
amp1
cline1
openclaw1
opencode1
cursor1
Automatically generates test mocks, stubs, and fixtures for various testing frameworks.
Ask the user or analyze code to determine:
Scan for testing framework:
# Check package.json for testing framework
grep -E "(jest|vitest|mocha|jasmine|pytest|unittest|minitest)" package.json
# Check for test files
find . -name "*.test.*" -o -name "*.spec.*" -o -name "test_*.py"
Function Mocks:
API Mocks:
Class Mocks:
Module Mocks:
Simple Function Mock:
// Mock a simple function
const mockFn = jest.fn()
mockFn.mockReturnValue(42)
// Use in test
test('uses mocked function', () => {
expect(mockFn()).toBe(42)
expect(mockFn).toHaveBeenCalled()
})
Function with Different Return Values:
const mockFn = jest.fn()
.mockReturnValueOnce('first')
.mockReturnValueOnce('second')
.mockReturnValue('default')
expect(mockFn()).toBe('first')
expect(mockFn()).toBe('second')
expect(mockFn()).toBe('default')
Mock Implementation:
const mockFn = jest.fn((x, y) => x + y)
expect(mockFn(1, 2)).toBe(3)
expect(mockFn).toHaveBeenCalledWith(1, 2)
Module Mock:
// __mocks__/axios.js
export default {
get: jest.fn(() => Promise.resolve({ data: {} })),
post: jest.fn(() => Promise.resolve({ data: {} })),
}
// In test file
jest.mock('axios')
import axios from 'axios'
test('fetches data', async () => {
axios.get.mockResolvedValue({ data: { name: 'John' } })
const result = await fetchUser(1)
expect(result.name).toBe('John')
expect(axios.get).toHaveBeenCalledWith('/users/1')
})
Class Mock:
// Mock a class
jest.mock('./Database')
import Database from './Database'
Database.mockImplementation(() => ({
query: jest.fn().mockResolvedValue([{ id: 1, name: 'John' }]),
connect: jest.fn().mockResolvedValue(true),
disconnect: jest.fn().mockResolvedValue(true),
}))
test('uses database', async () => {
const db = new Database()
const users = await db.query('SELECT * FROM users')
expect(users).toHaveLength(1)
expect(db.query).toHaveBeenCalled()
})
Partial Mock:
// Mock only specific methods
import * as utils from './utils'
jest.spyOn(utils, 'fetchData').mockResolvedValue({ data: 'mocked' })
test('uses mocked method', async () => {
const result = await utils.fetchData()
expect(result.data).toBe('mocked')
})
Function Mock:
import { vi, expect, test } from 'vitest'
const mockFn = vi.fn()
mockFn.mockReturnValue(42)
test('uses mock', () => {
expect(mockFn()).toBe(42)
})
Module Mock:
// __mocks__/api.ts
import { vi } from 'vitest'
export const fetchUser = vi.fn()
export const createUser = vi.fn()
// In test
vi.mock('./api')
import { fetchUser } from './api'
test('fetches user', async () => {
fetchUser.mockResolvedValue({ id: 1, name: 'John' })
const user = await fetchUser(1)
expect(user.name).toBe('John')
})
Spy on Method:
import { vi } from 'vitest'
const obj = {
method: () => 'original'
}
vi.spyOn(obj, 'method').mockReturnValue('mocked')
expect(obj.method()).toBe('mocked')
Type-Safe Mock:
import { vi } from 'vitest'
interface User {
id: number
name: string
email: string
}
// Create type-safe mock
const mockUser: User = {
id: 1,
name: 'John Doe',
email: 'john@example.com'
}
// Mock function with types
const mockFetchUser = vi.fn<[id: number], Promise<User>>()
mockFetchUser.mockResolvedValue(mockUser)
Mock Factory:
// Create a factory for generating mocks
function createMockUser(overrides?: Partial<User>): User {
return {
id: 1,
name: 'Test User',
email: 'test@example.com',
...overrides
}
}
// Use in tests
const user1 = createMockUser({ name: 'Alice' })
const user2 = createMockUser({ id: 2, email: 'bob@example.com' })
Function Mock:
from unittest.mock import Mock
# Simple mock
mock_func = Mock(return_value=42)
assert mock_func() == 42
assert mock_func.called
# Mock with side effects
mock_func = Mock(side_effect=[1, 2, 3])
assert mock_func() == 1
assert mock_func() == 2
assert mock_func() == 3
Patch Decorator:
from unittest.mock import patch, Mock
@patch('requests.get')
def test_fetch_data(mock_get):
# Setup mock
mock_response = Mock()
mock_response.json.return_value = {'name': 'John'}
mock_response.status_code = 200
mock_get.return_value = mock_response
# Test
result = fetch_user_data(1)
assert result['name'] == 'John'
mock_get.assert_called_once_with('https://api.example.com/users/1')
Class Mock:
from unittest.mock import Mock, patch
@patch('database.Database')
def test_database_query(mock_database_class):
# Setup mock instance
mock_db = Mock()
mock_db.query.return_value = [{'id': 1, 'name': 'John'}]
mock_database_class.return_value = mock_db
# Test
db = Database()
users = db.query('SELECT * FROM users')
assert len(users) == 1
assert users[0]['name'] == 'John'
mock_db.query.assert_called_once()
Context Manager Mock:
from unittest.mock import patch, mock_open
# Mock file operations
mock_data = "file contents"
with patch('builtins.open', mock_open(read_data=mock_data)):
with open('file.txt') as f:
content = f.read()
assert content == mock_data
Simple Fixture:
import pytest
@pytest.fixture
def mock_user():
return {
'id': 1,
'name': 'John Doe',
'email': 'john@example.com'
}
def test_user_data(mock_user):
assert mock_user['name'] == 'John Doe'
Fixture with Cleanup:
@pytest.fixture
def mock_database():
# Setup
db = MockDatabase()
db.connect()
yield db # Provide to test
# Teardown
db.disconnect()
def test_database_query(mock_database):
result = mock_database.query('SELECT * FROM users')
assert len(result) > 0
Parametrized Fixture:
@pytest.fixture(params=[
{'name': 'Alice', 'age': 25},
{'name': 'Bob', 'age': 30},
{'name': 'Charlie', 'age': 35}
])
def mock_user(request):
return request.param
def test_user_age(mock_user):
assert mock_user['age'] > 0
def test_api_call(mocker):
# Mock a function
mock_get = mocker.patch('requests.get')
mock_get.return_value.json.return_value = {'status': 'ok'}
result = fetch_data()
assert result['status'] == 'ok'
mock_get.assert_called_once()
// Mock fetch API
global.fetch = jest.fn(() =>
Promise.resolve({
ok: true,
status: 200,
json: async () => ({
id: 1,
name: 'John Doe',
email: 'john@example.com'
}),
headers: new Headers({
'Content-Type': 'application/json'
})
})
)
test('fetches user', async () => {
const user = await fetchUser(1)
expect(user.name).toBe('John Doe')
expect(fetch).toHaveBeenCalledWith('/api/users/1')
})
// mocks/handlers.js
import { rest } from 'msw'
export const handlers = [
rest.get('/api/users/:id', (req, res, ctx) => {
const { id } = req.params
return res(
ctx.status(200),
ctx.json({
id: Number(id),
name: 'John Doe',
email: 'john@example.com'
})
)
}),
rest.post('/api/users', (req, res, ctx) => {
return res(
ctx.status(201),
ctx.json({
id: 123,
...req.body
})
)
}),
rest.get('/api/users', (req, res, ctx) => {
return res(
ctx.status(200),
ctx.json([
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' }
])
)
})
]
// mocks/server.js
import { setupServer } from 'msw/node'
import { handlers } from './handlers'
export const server = setupServer(...handlers)
// setupTests.js
import { server } from './mocks/server'
beforeAll(() => server.listen())
afterEach(() => server.resetHandlers())
afterAll(() => server.close())
import { graphql } from 'msw'
export const handlers = [
graphql.query('GetUser', (req, res, ctx) => {
const { id } = req.variables
return res(
ctx.data({
user: {
id,
name: 'John Doe',
email: 'john@example.com'
}
})
)
}),
graphql.mutation('CreateUser', (req, res, ctx) => {
const { input } = req.variables
return res(
ctx.data({
createUser: {
id: '123',
...input
}
})
)
})
]
import { PrismaClient } from '@prisma/client'
import { mockDeep, mockReset, DeepMockProxy } from 'jest-mock-extended'
export const prismaMock = mockDeep<PrismaClient>()
beforeEach(() => {
mockReset(prismaMock)
})
// In test
test('creates user', async () => {
const mockUser = { id: 1, name: 'John', email: 'john@example.com' }
prismaMock.user.create.mockResolvedValue(mockUser)
const user = await createUser({ name: 'John', email: 'john@example.com' })
expect(user).toEqual(mockUser)
expect(prismaMock.user.create).toHaveBeenCalledWith({
data: { name: 'John', email: 'john@example.com' }
})
})
import { MongoMemoryServer } from 'mongodb-memory-server'
import { MongoClient } from 'mongodb'
let mongod
let client
let db
beforeAll(async () => {
mongod = await MongoMemoryServer.create()
const uri = mongod.getUri()
client = new MongoClient(uri)
await client.connect()
db = client.db()
})
afterAll(async () => {
await client.close()
await mongod.stop()
})
test('inserts user', async () => {
const users = db.collection('users')
const user = { name: 'John', email: 'john@example.com' }
await users.insertOne(user)
const found = await users.findOne({ name: 'John' })
expect(found.email).toBe('john@example.com')
})
import { render, screen } from '@testing-library/react'
import '@testing-library/jest-dom'
// Mock child component
jest.mock('./UserAvatar', () => ({
UserAvatar: ({ name }) => <div data-testid="avatar">{name}</div>
}))
test('renders user profile', () => {
render(<UserProfile name="John" />)
expect(screen.getByTestId('avatar')).toHaveTextContent('John')
})
import { renderHook } from '@testing-library/react'
// Mock useState
const mockSetState = jest.fn()
jest.spyOn(React, 'useState').mockImplementation(initial => [initial, mockSetState])
// Mock custom hook
jest.mock('./useUser')
import { useUser } from './useUser'
test('uses user hook', () => {
useUser.mockReturnValue({
user: { id: 1, name: 'John' },
loading: false,
error: null
})
const { result } = renderHook(() => useUser(1))
expect(result.current.user.name).toBe('John')
})
// fixtures/users.js
export const mockUsers = [
{ id: 1, name: 'Alice', email: 'alice@example.com', role: 'admin' },
{ id: 2, name: 'Bob', email: 'bob@example.com', role: 'user' },
{ id: 3, name: 'Charlie', email: 'charlie@example.com', role: 'user' }
]
export const mockUser = mockUsers[0]
// In tests
import { mockUser, mockUsers } from './fixtures/users'
test('processes user', () => {
const result = processUser(mockUser)
expect(result.name).toBe('Alice')
})
// factories/userFactory.js
let userId = 1
export function createUser(overrides = {}) {
return {
id: userId++,
name: 'Test User',
email: `user${userId}@example.com`,
role: 'user',
createdAt: new Date(),
...overrides
}
}
export function createAdmin(overrides = {}) {
return createUser({
role: 'admin',
...overrides
})
}
// In tests
import { createUser, createAdmin } from './factories/userFactory'
test('creates user', () => {
const user = createUser({ name: 'Alice' })
expect(user.name).toBe('Alice')
expect(user.role).toBe('user')
})
test('creates admin', () => {
const admin = createAdmin({ name: 'Bob' })
expect(admin.role).toBe('admin')
})
import factory
from myapp.models import User
class UserFactory(factory.Factory):
class Meta:
model = User
id = factory.Sequence(lambda n: n)
name = factory.Faker('name')
email = factory.Faker('email')
role = 'user'
# In tests
def test_user_creation():
user = UserFactory()
assert user.name is not None
assert '@' in user.email
def test_admin_creation():
admin = UserFactory(role='admin')
assert admin.role == 'admin'
// ❌ BAD: Overly complex mock
const mock = jest.fn()
mock.mockImplementation((a, b, c) => {
if (a > 10) {
return b * c
} else if (a < 5) {
return b + c
}
return a + b + c
})
// ✅ GOOD: Simple, focused mock
const mock = jest.fn().mockReturnValue(42)
// ✅ GOOD: Reusable factory
function createMockUser(overrides) {
return {
id: 1,
name: 'Test User',
email: 'test@example.com',
...overrides
}
}
afterEach(() => {
jest.clearAllMocks() // Clear call history
jest.resetAllMocks() // Clear call history + implementation
})
import { vi } from 'vitest'
const mockFn = vi.fn<[id: number], Promise<User>>()
// TypeScript ensures correct usage
mockFn(123) // ✅ OK
mockFn('abc') // ❌ TypeScript error
// Document why mock behaves this way
test('handles rate limiting', async () => {
// Mock returns 429 to simulate rate limiting
fetch.mockRejectedValueOnce(new Error('Rate limited'))
await expect(fetchData()).rejects.toThrow('Rate limited')
})
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation()
test('logs error', () => {
functionThatLogs()
expect(consoleErrorSpy).toHaveBeenCalledWith('Error occurred')
})
consoleErrorSpy.mockRestore()
jest.useFakeTimers()
test('delays execution', () => {
const callback = jest.fn()
setTimeout(callback, 1000)
jest.advanceTimersByTime(500)
expect(callback).not.toHaveBeenCalled()
jest.advanceTimersByTime(500)
expect(callback).toHaveBeenCalled()
})
jest.useRealTimers()
const mockDate = new Date('2024-01-01')
jest.spyOn(global, 'Date').mockImplementation(() => mockDate)
test('uses fixed date', () => {
const result = getCurrentDate()
expect(result.getFullYear()).toBe(2024)
})
Weekly Installs
1
Repository
GitHub Stars
4
First Seen
1 day ago
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
zencoder1
amp1
cline1
openclaw1
opencode1
cursor1
通过 LiteLLM 代理让 Claude Code 对接 GitHub Copilot 运行 | 高级变通方案指南
31,600 周安装