craft-coder/testing-anti-patterns/SKILL.md
Use when writing or changing tests, adding mocks, or tempted to add test-only methods to production code - prevents testing mock behavior and production pollution
npx skillsauth add timequity/plugins testing-anti-patternsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Tests must verify real behavior, not mock behavior. Mocks are a means to isolate, not the thing being tested.
Core principle: Test what the code does, not what the mocks do.
1. NEVER test mock behavior
2. NEVER add test-only methods to production classes
3. NEVER mock without understanding dependencies
The violation:
// ❌ BAD: Testing that the mock exists
test('renders sidebar', () => {
render(<Page />);
expect(screen.getByTestId('sidebar-mock')).toBeInTheDocument();
});
Why wrong: You're verifying the mock works, not that the component works.
The fix:
// ✅ GOOD: Test real component
test('renders sidebar', () => {
render(<Page />); // Don't mock sidebar
expect(screen.getByRole('navigation')).toBeInTheDocument();
});
BEFORE asserting on any mock element:
Ask: "Am I testing real behavior or just mock existence?"
IF mock existence: STOP - Delete assertion or unmock
The violation:
// ❌ BAD: destroy() only used in tests
class Session {
async destroy() { // Looks like production API!
await this._workspaceManager?.destroyWorkspace(this.id);
}
}
Why wrong: Production class polluted with test-only code.
The fix:
// ✅ GOOD: Test utilities handle cleanup
// In test-utils/
export async function cleanupSession(session: Session) {
const workspace = session.getWorkspaceInfo();
if (workspace) {
await workspaceManager.destroyWorkspace(workspace.id);
}
}
The violation:
// ❌ BAD: Mock breaks test logic
test('detects duplicate', () => {
vi.mock('ConfigWriter'); // Prevents config write test depends on!
await addServer(config);
await addServer(config); // Should throw - but won't!
});
Why wrong: Mocked method had side effect test depended on.
The fix:
// ✅ GOOD: Mock at correct level
test('detects duplicate', () => {
vi.mock('SlowNetworkCall'); // Mock only the slow part
await addServer(config); // Config written
await addServer(config); // Duplicate detected ✓
});
BEFORE mocking any method:
1. What side effects does the real method have?
2. Does this test depend on any of those side effects?
3. Do I fully understand what this test needs?
IF unsure: Run test with real implementation FIRST
The violation:
// ❌ BAD: Partial mock
const mockResponse = {
status: 'success',
data: { userId: '123' }
// Missing: metadata that downstream code uses
};
The fix:
// ✅ GOOD: Mirror real API completely
const mockResponse = {
status: 'success',
data: { userId: '123', name: 'Alice' },
metadata: { requestId: 'req-789', timestamp: 1234567890 }
};
| Anti-Pattern | Fix | |--------------|-----| | Assert on mock elements | Test real component or unmock | | Test-only methods in production | Move to test utilities | | Mock without understanding | Understand dependencies first | | Incomplete mocks | Mirror real API completely | | Tests as afterthought | TDD - tests first |
*-mock test IDsComplementary skills:
tools
Backup strategies, disaster recovery planning, and business continuity.
devops
Cloud cost management, rightsizing, and FinOps practices.
testing
CI/CD pipeline design with GitHub Actions, GitLab CI, and best practices.
development
Validate idea and create detailed PRD. Saves docs/PRD.md to project. Use when: user describes an app idea, wants to create something new. Triggers: "I want to build", "create app", "make website", "build MVP", "хочу создать", "сделать приложение".