Package Exports
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@halverscheid-fiae.de/angular-testing-factory) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@halverscheid-fiae.de/angular-testing-factory
Revolutionary type-safe Angular service mocking for Angular 20+
Zero Mock Driftβ’ guarantee with compile-time validation
π― Why This Library?
The Problem: Angular testing is painful. Manual mocks break when services change, TypeScript can't catch mock drift, and every new service needs tons of boilerplate.
The Solution: This library provides compile-time safe mocking with zero configuration for 90% of use cases, and zero mock drift for your custom services.
β¨ Revolutionary Features
- π― Zero Mock Driftβ’: TypeScript satisfiescatches mock inconsistencies at compile-time
- β‘ One-Line Providers: provideHttpClientMock()- Done!
- π Automated CI/CD: Semantic versioning with automatic NPM publishing
- π§ͺ 100% Test Coverage: All 88 tests pass with comprehensive coverage
- π― Squash & Merge: PR-based workflow with semantic commit messages
- π Override Anything: Per-test customization with the Factory Pattern
- π‘οΈ 100% Type Safe: Full IntelliSense and compile-time validation
- π¦ Angular 20+ Native: Signals, Standalone Components, modern inject()
- οΏ½ Zero Config: Works out-of-the-box with sensible defaults
π Quick Start
Installation
npm install --save-dev @halverscheid-fiae.de/angular-testing-factory90% Use Case: Preset Collections
import { TestBed } from '@angular/core/testing';
import { 
  provideHttpClientMock, 
  provideRouterMock, 
  provideMatDialogMock 
} from '@halverscheid-fiae.de/angular-testing-factory';
describe('MyComponent', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        provideHttpClientMock(),    // β HttpClient with sensible defaults
        provideRouterMock(),        // β Router with navigation mocks
        provideMatDialogMock()      // β MatDialog with dialog mocks
      ]
    });
  });
  it('should work perfectly', () => {
    // Your component gets fully mocked dependencies!
  });
});π₯ The Revolutionary Factory Pattern
Create Once, Override Everywhere
// 1. Create your factory ONCE (in test-setup.ts or similar)
const provideMyBusinessServiceMock = createServiceProviderFactory(MyBusinessService, {
  calculateRevenue: jest.fn(() => of(1000)),
  processPayment: jest.fn(() => Promise.resolve(false)),
  currentUser: signal({ id: 1, name: 'Test User' }),
  isLoading: signal(false)
});
// 2. Use everywhere with per-test overrides:
describe('Revenue Tests', () => {
  it('should handle high revenue', () => {
    TestBed.configureTestingModule({
      providers: [
        provideMyBusinessServiceMock({ 
          calculateRevenue: jest.fn(() => of(50000)) // β Override just this!
        })
      ]
    });
    // Test high revenue scenario
  });
  it('should handle payment failures', () => {
    TestBed.configureTestingModule({
      providers: [
        provideMyBusinessServiceMock({ 
          processPayment: jest.fn(() => Promise.reject('Card declined'))
        })
      ]
    });
    // Test payment failure scenario
  });
  it('should use sensible defaults', () => {
    TestBed.configureTestingModule({
      providers: [
        provideMyBusinessServiceMock() // β All defaults, no overrides
      ]
    });
    // Test normal flow
  });
});The Magic: Zero Mock Driftβ’
interface MyBusinessService {
  calculateRevenue(): Observable<number>;
  processPayment(amount: number): Promise<boolean>;
  currentUser: Signal<User>;
  isLoading: WritableSignal<boolean>;
}
// β
 This will catch ANY drift at compile-time:
const provideMyBusinessServiceMock = createServiceProviderFactory(MyBusinessService, {
  calculateRevenue: jest.fn(() => of(1000)),
  // β If you forget a method β TypeScript error!
  // β If you add wrong method β TypeScript error!  
  // β If return type changes β TypeScript error!
  // β If service interface changes β TypeScript error!
});import { of } from 'rxjs';
import { provideHttpClientMock } from '@halverscheid-fiae.de/angular-testing-factory';
// Mock HTTP calls with specific responses
TestBed.configureTestingModule({
  providers: [
    provideHttpClientMock({
      get: jest.fn(() => of({ data: 'custom response' })),
      post: jest.fn(() => of({ success: true }))
    })
  ]
});π API Reference
Core Functions
- createMockProvider<T>(token, mockService)- Creates Angular Provider for mocks
- createMockService<T>(defaults, overrides)- Creates type-safe mock objects
Preset Providers
Angular Common
- provideHttpClientMock(overrides?)- HttpClient Mock
- provideRouterMock(overrides?)- Router Mock
- provideLocationMock(overrides?)- Location Mock
- provideAngularCommonMocks()- All Common Services
Angular Material
- provideMatDialogMock(overrides?)- MatDialog Mock
- provideMatSnackBarMock(overrides?)- MatSnackBar Mock
- provideAngularMaterialMocks()- All Material Services
π οΈ Custom Services
3-Line Rule for New Services
// 1. Define service defaults
const MY_SERVICE_DEFAULTS: Partial<jest.Mocked<MyService>> = {
  getData: jest.fn(() => of([])),
  saveData: jest.fn(() => Promise.resolve())
};
// 2. Create factory
const createMockMyService = (overrides = {}) => 
  createMockService(MY_SERVICE_DEFAULTS, overrides);
// 3. Export provider
export const provideMyServiceMock = (overrides = {}) => 
  createMockProvider(MyService, createMockMyService(overrides));π SignalStore Testing
// β This does NOT work with SignalStores:
const spy = jest.spyOn(store.myService, 'getData'); // Error!
// β
 Correct approach for SignalStores:
const mockService = TestBed.inject(MyService); // After TestBed setup
const spy = jest.spyOn(mockService, 'getData');π‘ Why This Library?
Before (Traditional Approach)
// β Error-prone, lots of boilerplate, mock drift
const mockService = {
  getData: jest.fn(),
  setData: jest.fn(),
  // Forgotten methods lead to runtime errors
};
TestBed.configureTestingModule({
  providers: [
    { provide: MyService, useValue: mockService }
  ]
});After (With Angular Testing Factory)
// β
 Type-safe, 3-line rule, zero mock drift
TestBed.configureTestingModule({
  providers: [
    provideMyServiceMock({
      getData: jest.fn(() => of(customData))
    })
  ]
});ποΈ Architecture
@halverscheid-fiae.de/angular-testing-factory/
βββ π core/           # Universal Mock Factory System
βββ π¦ presets/        # Ready-to-use Service Mocks
βββ π― types/          # TypeScript Definitions
βββ π οΈ utils/          # Test Helper Utilitiesπ― Problem Solved
Traditional Angular testing suffers from:
- Mock Drift: Service changes break tests at runtime
- Boilerplate: Repetitive mock setup code
- Type Safety: Missing compile-time guarantees
- SignalStore Issues: Complex injection context handling
This library provides:
- Compile-time Safety: TypeScript satisfiescatches errors early
- DRY Principle: Reusable factories eliminate duplication
- Modern Angular: Built for standalone components and signals
- Developer Experience: 3-line rule for maximum productivity
π Requirements
- Angular 20+
- TypeScript 5.0+
- Jest 29+
- RxJS 7+
π€ Contributing
Contributions welcome! Please read our Contributing Guide.
Development Workflow
- Fork the repository
- Create your feature branch (git checkout -b feature/amazing-feature)
- Commit your changes following our commit conventions (see below)
- Push to the branch (git push origin feature/amazing-feature)
- Open a Pull Request
π Commit Message Conventions
This project uses automatic semantic versioning based on commit messages. Please follow these conventions:
Version Bumping Rules
π§ Patch Release (1.0.0 β 1.0.1):
git commit -m "fix: resolve HttpClient mock timeout issue"
git commit -m "docs: update installation instructions"  
git commit -m "chore: update dependencies"β¨ Minor Release (1.0.0 β 1.1.0):
git commit -m "feat: add MatSnackBar mock provider"
git commit -m "feat(presets): add Angular Forms mock collection"π₯ Major Release (1.0.0 β 2.0.0):
git commit -m "feat!: redesign API for better TypeScript inference"
git commit -m "refactor!: remove deprecated functions"
# Or with BREAKING CHANGE in body:
git commit -m "feat: redesign API for better TypeScript inference
BREAKING CHANGE: createMockProvider now requires explicit type parameter"Commit Types
- feat: New features β Minor version
- fix: Bug fixes β Patch version
- docs: Documentation β Patch version
- style: Code style β Patch version
- refactor: Code refactoring β Patch version
- test: Adding tests β Patch version
- chore: Maintenance β Patch version
Breaking Changes
Add BREAKING CHANGE: in commit body OR use ! after type for Major version:
# Option 1: ! suffix (recommended)
git commit -m "feat!: remove deprecated createLegacyMock function"  
git commit -m "refactor!: change API structure"
# Option 2: BREAKING CHANGE in body
git commit -m "refactor: improve type inference
BREAKING CHANGE: Generic type parameters order changed"π€ Automatic Publishing
When your PR is merged to main:
- β Version automatically bumped based on commit messages
- β
 Git tag created (e.g., v1.2.3)
- β NPM package published automatically
- β No manual steps required!
Example Workflow:
- You commit: feat: add new provider for Angular Router
- After merge: 1.0.0β1.1.0+ NPM publish + Git tagv1.1.0
π Issues
Found a bug? Please report it.
π License
MIT Β© Christian Halverscheid
π Made with β€οΈ for the Angular Community
This library was created to solve real-world testing challenges in enterprise Angular applications. Your feedback and contributions make it better!