ts-fake
v1.0.0
Published
Type-safe test utility for creating fakes of TypeScript interfaces and objects
Maintainers
Readme
ts-fake
Type-safe test utility for creating fakes of TypeScript interfaces and objects in unit tests.
Installation
npm install --save-dev ts-fakeQuick Start
import { fake } from "ts-fake";
interface User {
id: number;
name: string;
email: string;
}
// Create a type-safe fake with only the properties you need
const fakeUser = fake<User>({
id: 1,
name: "Test User",
});
// Use in your tests - email is undefined but type-safe
expect(fakeUser.id).toBe(1);
expect(fakeUser.name).toBe("Test User");Features
- Type-safe: Full TypeScript support with compile-time type checking
- Deep partial support: Nested objects work seamlessly
- Minimal boilerplate: Only specify the properties you need for your test
- Zero dependencies: Lightweight and fast
- Framework agnostic: Works with any testing framework (Jest, Vitest, Mocha, etc.)
Usage
Basic Example
import { fake } from "ts-fake";
interface Product {
id: string;
name: string;
price: number;
inStock: boolean;
}
// Only provide the fields you need for your test
const testProduct = fake<Product>({
id: "test-123",
name: "Test Product",
});
// Use in your tests
expect(testProduct.id).toBe("test-123");Nested Objects
interface Address {
street: string;
city: string;
country: string;
}
interface Customer {
id: string;
name: string;
address: Address;
}
// Deep partial support - only specify what you need
const testCustomer = fake<Customer>({
id: "cust-123",
name: "Jane Smith",
address: {
city: "New York",
},
});Advanced Usage
// Arrays and complex structures
interface Product {
id: string;
name: string;
}
interface Order {
id: string;
user: User;
items: Product[];
total: number;
}
const testOrder = fake<Order>({
id: "order-1",
user: {
id: 1,
name: "Test User",
},
items: [
{ id: "prod-1", name: "Widget" },
{ id: "prod-2", name: "Gadget" },
],
});API Documentation
fake<T>(partial?: DeepPartial<T>): T
Creates a type-safe fake object of type T.
Parameters:
partial(optional): A deep partial object containing the properties you want to set. If omitted, returns an empty object typed asT.
Returns:
- A complete object of type
Twith the provided properties
Type Safety:
- TypeScript will enforce that all provided properties match the interface
- The returned object is typed as
T, allowing it to be used anywhereTis expected - Supports deep partial objects - you can partially specify nested properties
Example:
// Empty fake
const emptyUser = fake<User>();
// Partial fake
const partialUser = fake<User>({ id: 1 });
// Deep partial fake
const customer = fake<Customer>({
address: { city: "NYC" }, // Only city, not full Address
});Why Use ts-fake?
Creating test data in TypeScript often involves choosing between several imperfect approaches. ts-fake provides a better alternative.
The Problem
interface User {
id: number;
name: string;
email: string;
createdAt: Date;
updatedAt: Date;
preferences: UserPreferences;
roles: Role[];
}
// Your test only needs id and nameAlternative Approaches (and their problems)
1. Type Assertion via unknown: {} as unknown as T
const user = { id: 1, name: "Test" } as unknown as User;❌ Bypasses all type checking - typos won't be caught
❌ Can pass invalid properties without errors
❌ No IDE autocomplete
2. Using Partial<T> directly
const user: Partial<User> = { id: 1, name: "Test" };
doSomething(user); // ❌ Type error: Partial<User> is not assignable to User❌ Can't pass to functions expecting User
❌ Requires casting anyway: user as User
❌ Loses type safety when casting
3. Providing the full interface
const user: User = {
id: 1,
name: "Test",
email: "[email protected]",
createdAt: new Date(),
updatedAt: new Date(),
preferences: { theme: "dark", language: "en" },
roles: [],
};❌ Verbose and tedious
❌ Brittle - breaks when interface changes
❌ Obscures what the test actually needs
4. Refactoring with Interface Segregation Principle (ISP)
interface UserIdentity {
id: number;
name: string;
}
function doSomething(user: UserIdentity) { ... }❌ Not always practical - you don't control all interfaces
❌ Over-engineering for test purposes
❌ Doesn't help with third-party types
The ts-fake Solution
const user = fake<User>({ id: 1, name: "Test" });
doSomething(user); // ✅ Works perfectly✅ Type-safe: Properties are validated against the interface
✅ Minimal: Only specify what your test needs
✅ Flexible: Works with any interface, including third-party types
✅ Maintainable: Tests don't break when unused properties change
✅ Clear intent: Shows exactly what the test depends on
✅ IDE support: Full autocomplete and type checking
Contributing
Contributions are welcome! See CONTRIBUTING.md for guidelines.
License
MIT © laazyj
