Agent skill

Typescript Test Doubles

by macalbert in macalbert/envilder

Test doubles with Vitest (vi.fn, vi.mock, vi.spyOn) and Mother pattern.

MITAuto-check passedTesting & QA

Install Typescript Test Doubles

skills CLI
$ npx skills add macalbert/envilder --skill typescript-test-doubles -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install macalbert/envilder typescript-test-doubles --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/macalbert/envilder.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.github/skills/typescript-test-doubles .claude/skills/typescript-test-doubles && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
typescript-test-doubles
GitHub stars
138
Token cost
~1.2k tokens
SKILL.md length
216 words
Files
1
Skills in repo
30
Repo updated
First seen
Licence
MIT

At a glance

Test doubles with Vitest (vi.fn, vi.mock, vi.spyOn) and Mother pattern.

  • Works in 5 steps: Mock: vi.fn() → Stub: mockResolvedValue / mockReturnValue → Spy: vi.spyOn() → …
  • Creating test data
  • SKILL.md covers Test Doubles Types, Verification Patterns, Mother Pattern and Port Test Double Pattern, plus 1 more section
  • Needs API_KEY

What it does

Typescript Test Doubles is an agent skill from macalbert/envilder. Test doubles with Vitest (vi.fn, vi.mock, vi.spyOn) and Mother pattern. Use when creating test data, mocking dependencies, or setting up module mocks in TypeScript tests.

Its SKILL.md is about 1.2k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Testing & QA, covering Unit testing. It works with TypeScript and Vitest. The repository describes itself as: One secret mapping for local dev, CI/CD, and runtime. Envilder resolves cloud secrets from your own vaults without SaaS middlemen, duplicated config, or .env drift. The licence is MIT.

When your agent uses it

  • Creating test data
  • Mocking dependencies
  • Setting up module mocks in TypeScript tests

Example prompts

  • “/typescript-test-doubles”

Requirements

  • A credential in API_KEY

Workflow steps

5 steps, taken from the step headings in SKILL.md.

  1. Mock: vi.fn()
  2. Stub: mockResolvedValue / mockReturnValue
  3. Spy: vi.spyOn()
  4. Module Mock: vi.mock()
  5. Error Simulation: mockRejectedValue

What it can do on your machine

Read from SKILL.md and the folder at commit b6a0327. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md (its code samples are typescript).

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • API_KEY

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Typescript Test Doubles loads about 1.2k tokens when it runs. Until then it costs about 49 tokens; SKILL.md has 216 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~49
When it runs · the whole SKILL.md, loaded when a task matches
~1.2k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from macalbert/envilder at commit b6a0327, republished under its MIT licence (© macalbert). 216 words, ~1,204 tokens.

Download SKILL.mdSave it as .claude/skills/typescript-test-doubles/SKILL.md (or your agent's skills folder).
name
typescript-test-doubles
description
Test doubles with Vitest (vi.fn, vi.mock, vi.spyOn) and Mother pattern. Use when creating test data, mocking dependencies, or setting up module mocks in TypeScript tests.

Test Doubles (TypeScript)

This skill defines how to use test doubles in TypeScript (Vitest).


Test Doubles Types

1. Mock: vi.fn()

Use vi.fn() to create mock functions for port interfaces.

Purpose: Replace real dependencies with controllable test doubles.

typescript
const mockProvider: ISecretProvider = {
  getSecret: vi.fn(),
};

const mockStore: IVariableStore = {
  getMapping: vi.fn(),
  saveEnvironment: vi.fn(),
};

const mockLogger: ILogger = {
  info: vi.fn(),
  warn: vi.fn(),
  error: vi.fn(),
};
2. Stub: mockResolvedValue / mockReturnValue

Use return value methods to configure stubs.

Purpose: Predefined responses without caring about call verification.

typescript
// Async stub
mockProvider.getSecret.mockResolvedValue('secret-value');
mockStore.getMapping.mockResolvedValue({ KEY: '/ssm/path' });

// Sync stub
mockParser.parse.mockReturnValue({ config: {}, mappings: {} });

// Sequential returns
mockProvider.getSecret
  .mockResolvedValueOnce('first')
  .mockResolvedValueOnce('second');
3. Spy: vi.spyOn()

Use vi.spyOn() to observe calls on real objects without replacing behavior.

Purpose: Verify interactions while preserving real implementation.

typescript
const spy = vi.spyOn(console, 'log');

sut.execute();

expect(spy).toHaveBeenCalledWith('Processing...');
spy.mockRestore();
4. Module Mock: vi.mock()

Use vi.mock() to replace entire modules.

Purpose: Replace external dependencies (AWS SDK, file system, etc.).

typescript
vi.mock('@aws-sdk/client-ssm', () => ({
  SSMClient: vi.fn().mockImplementation(() => ({
    send: vi.fn(),
  })),
  GetParameterCommand: vi.fn(),
}));
5. Error Simulation: mockRejectedValue

Use mockRejectedValue() to simulate failures.

Purpose: Test error paths and exception handling.

typescript
mockProvider.getSecret.mockRejectedValue(
  new ParameterNotFoundError('/missing/key'),
);

mockStore.getMapping.mockRejectedValue(
  new Error('File not found'),
);

Verification Patterns

Basic Verification
typescript
expect(mockProvider.getSecret).toHaveBeenCalledWith('/ssm/path');
expect(mockProvider.getSecret).toHaveBeenCalledTimes(1);
expect(mockLogger.info).toHaveBeenCalledWith(
  expect.stringContaining('success'),
);
Not Called
typescript
expect(mockStore.saveEnvironment).not.toHaveBeenCalled();
expect(mockLogger.error).not.toHaveBeenCalled();
Call Order
typescript
expect(mockProvider.getSecret).toHaveBeenCalledBefore(
  mockStore.saveEnvironment,
);
Argument Matchers
typescript
expect(mockLogger.info).toHaveBeenCalledWith(
  expect.stringMatching(/loaded \d+ secrets/),
);
expect(mockStore.saveEnvironment).toHaveBeenCalledWith(
  expect.objectContaining({ KEY: 'value' }),
);

Mother Pattern

Use factory functions for reusable test data creation.

typescript
function createParsedMapFile(
  overrides: Partial<ParsedMapFile> = {},
): ParsedMapFile {
  return {
    config: { provider: 'aws' },
    mappings: new Map([['DB_URL', '/app/db']]),
    ...overrides,
  };
}

function createEnvilderOptions(
  overrides: Partial<EnvilderOptions> = {},
): EnvilderOptions {
  return {
    provider: SecretProviderType.AWS,
    profile: undefined,
    vaultUrl: undefined,
    ...overrides,
  };
}

Usage:

typescript
// Arrange
const mapFile = createParsedMapFile({
  mappings: new Map([['API_KEY', '/prod/api-key']]),
});

Port Test Double Pattern

Build complete mock objects implementing domain interfaces:

typescript
function createMockSecretProvider(): ISecretProvider & {
  getSecrets: Mock;
} {
  return {
    getSecrets: vi.fn().mockResolvedValue(new Map()),
  };
}

function createMockLogger(): ILogger & {
  info: Mock;
  warn: Mock;
  error: Mock;
} {
  return {
    info: vi.fn(),
    warn: vi.fn(),
    error: vi.fn(),
  };
}

Summary

Double TypeVitest APIPurpose
Mockvi.fn()Controllable replacement
Stub.mockResolvedValue() / .mockReturnValue()Predefined responses
Spyvi.spyOn()Observe real objects
Module mockvi.mock()Replace entire modules
Error sim.mockRejectedValue()Failure paths

When writing tests:

  1. Create port test doubles with vi.fn() in beforeEach
  2. Configure stubs with .mockResolvedValue() in Arrange
  3. Always verify mock interactions in Assert
  4. Use Mother pattern for complex test data
  5. Prefer vi.fn() over vi.mock() (port-level > module-level)

© macalbert, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .github/skills/typescript-test-doubles of macalbert/envilder.

Open the folder on GitHubat commit b6a0327

Compare with similar skills

Typescript Test Doubles next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Typescript Test Doubles compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Typescript Test Doubles this skillmacalbert/envilder138—~1.2kAutomated safety check: PassMIT
Test Writing WorkflowiOfficeAI/AionUi33k1 repos~1.2kAutomated safety check: PassApache-2.0
Creating A Packagec15t/c15t1.9k—~913Automated safety check: PassApache-2.0
Svelte Testingspences10/sveltest113—~579Automated safety check: PassMIT
Effect TStellahq/opensession392—~3.7kAutomated safety check: PassMIT
Ha Frontend Testinghome-assistant/frontend5.7k—~1.7kAutomated safety check: PassApache-2.0

Similar skills

  • Test Writing Workflow

    iOfficeAI/AionUi

    Sets the test-writing workflow for the repository: risk-first scenario lists, behavior-focused Vitest tests, a full run before each commit and a coverage target.

    33k GitHub starsUsed in 1 repo~1.2k tokens
    Testing & QAAuto-check passed
  • Scaffold a new workspace package in the c15t monorepo. An agent skill from c15t/c15t.

    1.9k GitHub stars~913 tokensUpdated today
    Testing & QAAuto-check passed
  • Svelte Testing

    spences10/sveltest

    Fix and create Svelte 5 tests with vitest-browser-svelte and Playwright.

    113 GitHub stars~579 tokensUpdated yesterday
    Testing & QAAuto-check passed
  • Effect TS

    tellahq/opensession

    Write idiomatic Effect v4 TypeScript verified against the pinned effect@4.0.0-rc.112 source.

    392 GitHub stars~3.7k tokensUpdated today
    Testing & QAAuto-check passed
  • Ha Frontend Testing

    home-assistant/frontend

    Home Assistant frontend testing and validation workflow. An agent skill from home-assistant/frontend.

    5.7k GitHub stars~1.7k tokensUpdated today
    Testing & QAAuto-check passed
  • Eslint Vitest Rule Tester

    antfu-collective/eslint-vitest-rule-tester

    Help users test ESLint rules with Vitest, supporting snapshot testing and custom assertions

    142 GitHub stars~1.3k tokensUpdated 27 days ago
    Testing & QAAuto-check passed

More from macalbert/envilder

All 30 skills in this repo
  • Code Review Perspectives

    macalbert/envilder

    Five independent analysis perspectives for code review: correctness, architecture, security, conventions, and complexity.

    138 GitHub stars~1k tokensUpdated 2 days ago
    Auto-check passed
  • Index of Architecture Decision Records (ADRs) for cross-cutting technical decisions.

    138 GitHub stars~1.3k tokensUpdated 2 days ago
    Auto-check passed
  • Common Git

    macalbert/envilder

    Git commit messages, PR workflow, and branching strategy using Conventional Commits and Semantic Versioning.

    138 GitHub stars~991 tokensUpdated 2 days ago
    Auto-check passed
  • Common Testing Conventions

    macalbert/envilder

    Mandatory testing conventions including the narrow diagnostic exception for testing test-only code, AAA pattern, test naming, and assertions across all stacks (.NET, TypeScript, Python).

    138 GitHub stars~1.9k tokensUpdated 2 days ago
    Auto-check passed
  • Doc Maintenance

    macalbert/envilder

    Workflow for maintaining changelogs, READMEs, and documentation files.

    138 GitHub stars~904 tokensUpdated 2 days ago
    Auto-check passed
  • Doc Sync

    macalbert/envilder

    Audit and synchronize documentation across website, READMEs, and docs/.

    138 GitHub stars~1.3k tokensUpdated 2 days ago
    Auto-check passed

Categories

Questions about Typescript Test Doubles

What does Typescript Test Doubles do?

Test doubles with Vitest (vi.fn, vi.mock, vi.spyOn) and Mother pattern. Typescript Test Doubles is an agent skill from macalbert/envilder.spyOn) and Mother pattern.

When should I use Typescript Test Doubles?

Typescript Test Doubles fits situations like: creating test data; mocking dependencies; setting up module mocks in TypeScript tests.

How do I install Typescript Test Doubles in Claude Code?

Run `npx skills add macalbert/envilder --skill typescript-test-doubles -a claude-code`. Or copy the skill folder (.github/skills/typescript-test-doubles in macalbert/envilder) into .claude/skills/typescript-test-doubles in your project. Claude Code loads it when a task matches its description.

How do I install Typescript Test Doubles in Codex?

Run `npx skills add macalbert/envilder --skill typescript-test-doubles -a codex`. Or copy the skill folder (.github/skills/typescript-test-doubles in macalbert/envilder) into .agents/skills/typescript-test-doubles in your project. Codex loads it when a task matches its description.

Can I use Typescript Test Doubles in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add macalbert/envilder --skill typescript-test-doubles -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/typescript-test-doubles, .gemini/skills/typescript-test-doubles, .github/skills/typescript-test-doubles and .opencode/skills/typescript-test-doubles in your project.

What does Typescript Test Doubles need to run?

Going by SKILL.md and its folder, Typescript Test Doubles needs credentials named API_KEY. Our summary lists: A credential in API_KEY.

Does Typescript Test Doubles access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Typescript Test Doubles safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Typescript Test Doubles use?

Typescript Test Doubles is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Typescript Test Doubles use?

About 1.2k tokens (SKILL.md is roughly 4.8k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Typescript Test Doubles?

Skills that share tags, products or a category with Typescript Test Doubles: Test Writing Workflow (iOfficeAI/AionUi, 33k stars), Creating A Package (c15t/c15t, 1.9k stars), Svelte Testing (spences10/sveltest, 113 stars) and Effect TS (tellahq/opensession, 392 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Typescript Test Doubles?

macalbert (a GitHub user) maintains it in macalbert/envilder, which has 138 GitHub stars. The repository holds 30 skills in this directory. The repository was last updated on October 5, 2026.

Source: macalbert/envilder on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.