Mock components, services, and more to simplify Angular testing
ng-mocks simplifies Angular testing and helps you:
- mock Components, Directives, Pipes, Modules, Services and Tokens
- reduce boilerplate in tests
- access declarations through a simple interface
| angular | ng-mocks | jasmine | jest | vitest | ivy | standalone | signals | defer | | ------: | :------: | :-----: | :--: | :----: | :-: | :--------: | :-----: | :---: | | 22 | latest | yes | yes | yes | yes | yes | yes | yes | | 21 | latest | yes | yes | yes | yes | yes | yes | yes | | 20 | latest | yes | yes | yes | yes | yes | yes | yes | | 19 | latest | yes | yes | | yes | yes | yes | yes | | 18 | latest | yes | yes | | yes | yes | yes | yes | | 17 | latest | yes | yes | | yes | yes | yes | yes | | 16 | latest | yes | yes | | yes | yes | yes | | | 15 | latest | yes | yes | | yes | yes | | | | 14 | latest | yes | yes | | yes | yes | | | | 13 | latest | yes | yes | | yes | | | | | 12 | latest | yes | yes | | yes | | | | | 11 | latest | yes | yes | | yes | | | | | 10 | latest | yes | yes | | yes | | | | | 9 | latest | yes | yes | | yes | | | | | 8 | latest | yes | yes | | | | | | | 7 | latest | yes | yes | | | | | | | 6 | latest | yes | yes | | | | | | | 5 | latest | yes | yes | | | | | |
Angular 20's native Vitest support is zoneless-only because its supported Zone.js version has no Vitest patch.
Important links
- Live example on CodeSandbox
- Live example on StackBlitz
- start a discussion on GitHub
- ask a question on Stackoverflow
- report an issue on GitHub
- chat on gitter
Very short introduction
Put the global configuration for mocks in the setup file for your test runner.
For Jasmine, use src/test.ts.
For Jest, use src/setup-jest.ts / src/test-setup.ts.
For Vitest, use src/setup-vitest.ts and follow the
native Angular setup.
``ts title="src/test.ts"
// All methods in mock declarations and providers
// will be automatically spied on their creation.
// https://ng-mocks.sudo.eu/extra/auto-spy
ngMocks.autoSpy('jasmine');
// In setup-jest.ts: ngMocks.autoSpy('jest');
// In setup-vitest.ts: ngMocks.autoSpy('vitest');
// ngMocks.defaultMock helps to customize mocks // globally. Therefore, we can avoid copy-pasting // among tests. // https://ng-mocks.sudo.eu/api/ngMocks/defaultMock ngMocks.defaultMock(AuthService, () => ({ isLoggedIn$: EMPTY, currentUser$: EMPTY, }));
An example of a spec for a profile edit component.ts title="src/profile.component.spec.ts"
// Let's imagine that there is a ProfileComponent
// and it has 3 text fields: email, firstName,
// lastName, and a user can edit them.
// In the following test suite, we would like to
// cover the behavior of the component.
describe('profile:builder', () => {
// Helps to reset customizations after each test.
// Alternatively, you can enable
// automatic resetting in test.ts.
MockInstance.scope();
// Let's configure TestBed via MockBuilder. // The code below says to mock everything in // ProfileModule except ProfileComponent and // ReactiveFormsModule. beforeEach(() => { // The result of MockBuilder should be returned. // https://ng-mocks.sudo.eu/api/MockBuilder return MockBuilder( ProfileComponent, ProfileModule, ).keep(ReactiveFormsModule); // // or the old-fashioned way // return TestBed.configureTestingModule({ // imports: [ // MockModule(SharedModule), // mock // ReactiveFormsModule, // real // ], // declarations: [ // ProfileComponent, // real // MockPipe(CurrencyPipe), // mock // MockDirective(HoverDirective), // mock // ], // providers: [ // MockProvider(AuthService), // mock // ], // }).compileComponents(); });
// A test to ensure that ProfileComponent
// can be created.
it('should be created', () => {
// MockRender is an advanced version of
// TestBed.createComponent.
// It respects all lifecycle hooks,
// onPush change detection, and creates a
// wrapper component with a template like
//
expect( fixture.point.componentInstance, ).toEqual(jasmine.any(ProfileComponent)); });
// A test to ensure that the component listens // on ctrl+s hotkey. it('saves on ctrl+s hot key', () => { // A fake profile. const profile = { email: '[email protected]', firstName: 'testFirst2', lastName: 'testLast2', };
// A spy to track save calls. // MockInstance helps configure mock // providers, declarations and modules // before their initialization and usage. // https://ng-mocks.sudo.eu/api/MockInstance const spySave = MockInstance( StorageService, 'save', jasmine.createSpy(), // or jest.fn() );
// Renders
// Let's change the value of the form control // for email addresses with a random value. // ngMocks.change finds a related control // value accessor and updates it properly. // https://ng-mocks.sudo.eu/api/ngMocks/change ngMocks.change( '[name=email]', // css selector '[email protected]', // an email address );
// Let's ensure that nothing has been called. expect(spySave).not.toHaveBeenCalled();
// Let's assume that there is a host listener // for a keyboard combination of ctrl+s, // and we want to trigger it. // ngMocks.trigger helps to emit events via // simple interface. // https://ng-mocks.sudo.eu/api/ngMocks/trigger ngMocks.trigger(point, 'keyup.control.s');
// The spy should be called with the profile
// and the random email address.
expect(spySave).toHaveBeenCalledWith({
email: '[email protected]',
firstName: profile.firstName,
lastName: profile.lastName,
});
});
});
`
Profit.
Extra
If you like ng-mocks`, please support it:
Thank you!P.S. Feel free to contact us if you need help.