npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@test-effective/fakes

v0.3.0

Published

Test Effective Fakes

Readme

Fake Server Utils for UI Component Tests 🎭

A powerful testing utility library designed to simplify creating and managing a fake server layer for UI component tests.

(No real data was harmed in the making of this library... 😉)

What's a fake server layer?

A fake server layer needs two things to successfully simulate a real server:

  1. A way to store and manipulate data the same way the real server would.
  2. A way to react to http requests the way a real server would.

Test Effective Fakes provides two powerful features to help you create and manage a fake server layer:

Faketories

A util on top of MSW Data for making it easier to seed or generate fake test data with automatic partial merging, relational seeding and more.

Fakepoints

Auto-discovery system for organizing test setup code. Instead of manually importing MSW handlers across test files, fakepoints automatically discover and register your fake endpoints at a predictable time.

Table of Contents

Requirements

  • @msw/data ^1.0.0 (peer dependency)
  • Vite (if you're using the fakepoints plugin)

Installation

pnpm install -D @test-effective/fakes @msw/data

Recommended Additional Libraries

For the best experience, we recommend installing these additional libraries:

pnpm install -D @test-effective/fakes @msw/data @faker-js/faker valibot
  • @faker-js/faker - Generate realistic fake data for your faketories
  • valibot - Schema validation library (but you can use zod or any other standard schema implementation)

1. Faketories

Faketories are factories for generating fake test data.

Basically, "factories of fakes"... "Faketories"... yeah, we know, great pun 😅.

They provide four methods:

  • generateOne() / generateMany() - Generate standalone entities (not stored in DB)
  • seedOne() / seedMany() - Generate and store entities in your MSW Data collection

1.1 Create a Faketory

import { createFaketory } from '@test-effective/fakes';
import { Collection } from '@msw/data';
import { faker } from '@faker-js/faker';
import * as v from 'valibot';

// Define your fake db table schema (supports all standard schema implementations)
const userSchema = v.object({
  id: v.string(),
  email: v.string(),
  name: v.string(),
});

// Create a MSW data collection, we called it 'store' because it's shorter.
const userStore = new Collection({ schema: userSchema });

const userFaketory = createFaketory(
  userStore, // MSW Data Store
  async ({ seedingMode, index, partial }) => {
    // Return default values
    // partial is automatically merged - no need to spread it!
    return {
      id: faker.string.uuid(),
      email: faker.internet.email(),
      name: faker.person.fullName()
    };
});

// Use it in tests
const user = await userFaketory.seedOne({ email: '[email protected]' });

// Use it in fakepoints
const users = userFaketory.store.findMany();

Props available in your faketory function:

  • seedingMode - is 'true' when called with one of the seeding methods.
  • index - when creating many entities, this is the index of the entity being created.
  • partial - Override default values created by the faketory function

Auto-Merge Magic ✨

Partial data is automatically merged with defaults so you don't need to spread ...partial in the end of your faketory function.

1.2 The generateOne() Method

Generates a single standalone entity (not stored in the fake DB):

// Single entity with defaults
const user = await userFaketory.generateOne();

// Single entity with overrides (auto-merged!)
const admin = await userFaketory.generateOne({ email: '[email protected]' });

1.3 The generateMany() Method

Generates multiple standalone entities (not stored in the fake DB):

// Multiple entities (returns array)
const users = await userFaketory.generateMany(5);

// Multiple entities with custom data (returns array, auto-merged!)
const users = await userFaketory.generateMany([
  { email: '[email protected]' },
  { email: '[email protected]' },
]);

// Generate N entities, merge partials by index (auto-merged!)
const users = await userFaketory.generateMany(3, [
  { email: '[email protected]' },
]);
// Creates 3 entities:
// - users[0] has email: '[email protected]' (merged with defaults)
// - users[1] uses all defaults
// - users[2] uses all defaults

1.4 The seedOne() Method

Creates and stores a single entity in the MSW Data store:

// Single entity (returns T)
const user = await userFaketory.seedOne();

// Single entity with overrides (returns T, auto-merged!)
const admin = await userFaketory.seedOne({ email: '[email protected]' });

1.5 The seedMany() Method

Creates and stores multiple entities in the MSW Data store:

// Multiple entities (returns T[])
const users = await userFaketory.seedMany(10);

// Multiple entities with custom data (returns T[], auto-merged!)
const users = await userFaketory.seedMany([
  { email: '[email protected]' },
  { email: '[email protected]' },
]);

// Seed N entities, merge partials by index (auto-merged!)
const users = await userFaketory.seedMany(5, [
  { email: '[email protected]', name: 'Admin' },
  { email: '[email protected]' },
]);
// Creates 5 entities in the store:
// - users[0] has email: '[email protected]' and name: 'Admin'
// - users[1] has email: '[email protected]' (other fields use defaults)
// - users[2-4] use all defaults

1.6 Direct Store Access

Need to query or update your fake data? No problem!

Access the MSW Data collection directly via the store property.

Why "store" and not "collection"?

Honestly? Because store is shorter than collection 😊

Under the hood, store is the MSW Data Collection instance, giving you full access to all its methods:

// Query all users
const allUsers = userFaketory.store.findMany();

// Find specific user
const user = userFaketory.store.findFirst(q => 
  q.where({ email: '[email protected]' })
);

// Update user
userFaketory.store.update({
  where: { id: user.id },
  data: { name: 'Updated Name' },
});

// Delete user
userFaketory.store.delete({ where: { id: user.id } });

1.7 Resetting Data

Sometimes you need to hit the reset button (we've all been there):

// Reset a single faketory
userFaketory.reset();

1.8 ⚠️ IMPORTANT: Preventing Stale Data

Always call resetAllFaketories() in a global beforeEach hook to prevent stale data from previous tests. Without this, entities created in one test can leak into subsequent tests, causing flaky and unpredictable test failures.

// tests-setup.ts
import { resetAllFaketories } from '@test-effective/fakes';
import { beforeEach } from 'vitest';

beforeEach(() => {
  resetAllFaketories(); // Clears all faketory collections before each test
});

2. Fakepoints

Fakepoints (Fake Endpoints, we're very creative with naming here 🎯) are registration points for setting up the fake remote endpoints layer for your tests.

Instead of manually importing MSW handlers across your test files, fakepoints auto-discover them and let you set them up at a predictable time.

2.1 How It Works

  1. You create .fakepoints.ts files (or use a custom pattern via the filePattern option) and use the registerFakepoints() function to register your fake endpoints.
  2. The Vite plugin scans your workspace for all matching files and creates a virtual module collected-fakepoints that imports them all.
  3. When you call runAllFakepoints(), all registered functions run.

Use cases:

  • Registering MSW handlers
  • Replacing remote services with fake ones

2.2 Setup

  1. Add the Vite plugin to your vite.config.ts:
import { collectFakepointsPlugin } from '@test-effective/fakes';

export default defineConfig({
  plugins: [
    collectFakepointsPlugin({
      workspaceRoot: '../../your/project/root', // Optional, defaults to process.cwd()
      filePattern: '.fakepoints.ts', // Optional, file pattern to match (default: '.fakepoints.ts')
      debug: false, // Optional, enables debug logging
      watch: true, // Optional, enables file watching for auto test reruns (default: true)
      ignoreDirs: ['tmp', '.nx', 'coverage'], // Optional, directories to ignore when scanning
    }),
  ],
});

Configuration Options:

  • workspaceRoot (optional) - Root directory to scan for fakepoints files. Defaults to process.cwd().

  • filePattern (optional, default: '.fakepoints.ts') - The file pattern to match when scanning for fakepoints files. This allows you to use a custom naming convention for your fakepoints files.

    Examples:

    filePattern: '.fakes.ts'      // Match *.fakes.ts files
    filePattern: '.test-data.ts'  // Match *.test-data.ts files
    filePattern: '.fixtures.ts'   // Match *.fixtures.ts files
  • watch (optional, default: true) - Enable file watching for fakepoints files. When enabled, adding, deleting, or changing fakepoints files will automatically trigger test reruns. Disable this if you experience performance issues with large workspaces.

  • ignoreDirs (optional) - Array of directory names to ignore when scanning for fakepoints files during initial collection. Note: Vite's watcher automatically ignores .git, node_modules, test-results, cache, and configured out directories. Common directories to add: 'tmp', '.nx', 'coverage', 'build', 'out', 'dist', '.cache'.

  • debug (optional, default: false) - Enable debug mode to see detailed logging about plugin operations including:

    • Watcher ignore patterns being configured
    • Virtual module loading
    • Number of fakepoints files loaded
    • File watcher setup status
    • All file system events for fakepoints files (add, change, unlink)

    Useful for troubleshooting issues with file discovery, watching, or test reruns.

  1. Create fakepoints files anywhere in your project (default pattern: .fakepoints.ts):
// src/users/user.fakepoints.ts
import { registerFakepoints } from '@test-effective/fakes';
import { setupUserHandlers } from './handlers';

registerFakepoints(() => {
  setupUserHandlers();
  console.log('✅ User fakepoints registered');
});
// src/posts/post.fakepoints.ts
import { registerFakepoints } from '@test-effective/fakes';
import { setupPostHandlers } from './handlers';

registerFakepoints(() => {
  setupPostHandlers();
});
  1. Import the virtual module in your test setup (this is where the magic happens ✨):
// tests-setup.ts
import 'collected-fakepoints'; // Auto-imports all fakepoints files
import { runAllFakepoints } from '@test-effective/fakes';
import { beforeAll } from 'vitest';

beforeAll(() => {
  runAllFakepoints(); // Runs all registered fakepoints
});

2.3 Collecting Values from Fakepoints

Fakepoints can also return values that are collected when you call runAllFakepoints(). This is especially useful for collecting provider arrays (like in Angular), configuration objects, or any other test setup data that needs to be gathered from multiple files.

Basic Example - Collecting Values

// src/users/user.fakepoints.ts
import { registerFakepoints } from '@test-effective/fakes';

registerFakepoints(() => {
  return { module: 'users', handlers: 3 };
});
// src/posts/post.fakepoints.ts
import { registerFakepoints } from '@test-effective/fakes';

registerFakepoints(() => {
  return { module: 'posts', handlers: 2 };
});
// tests-setup.ts
import 'collected-fakepoints';
import { runAllFakepoints } from '@test-effective/fakes';

type ModuleInfo = { module: string; handlers: number };
const modules = runAllFakepoints<ModuleInfo>();
// Result: [{ module: 'users', handlers: 3 }, { module: 'posts', handlers: 2 }]

Contributing

Want to contribute? Yayy! 🎉

Please read and follow our Contributing Guidelines to learn what are the right steps to take before contributing your time, effort and code.

Thanks 🙏

Code Of Conduct

Be kind to each other and please read our code of conduct.

License

MIT