Mock components, services and more out of annoying dependencies for simplification of Angular testing
ng-mocks facilitates Angular testing and helps to:
- mock Components, Directives, Pipes, Modules, Services and Tokens
- reduce boilerplate in tests
- access declarations via simple interface
The current version of the library has been tested and can be used with:
| angular | ng-mocks | jasmine | jest | ivy | standalone | signals | defer |
|---|---|---|---|---|---|---|---|
| 19 | latest | yes | yes | yes | yes | no | no |
| 18 | latest | yes | yes | yes | yes | no | no |
| 17 | latest | yes | yes | yes | yes | no | no |
| 16 | latest | yes | yes | yes | yes | no | |
| 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 |
Global configuration for mocks in src/test.ts.
In case of jest, src/setup-jest.ts / src/test-setup.ts should be used.
// All methods in mock declarations and providers// will be automatically spied on their creation.// https://ng-mocks.sudo.eu/extra/auto-spyngMocks.autoSpy('jasmine');// or jest// ngMocks.defaultMock helps to customize mocks// globally. Therefore, we can avoid copy-pasting// among tests.// https://ng-mocks.sudo.eu/api/ngMocks/defaultMockngMocks.defaultMock(AuthService,()=>({isLoggedIn$: EMPTY,currentUser$: EMPTY,}));An example of a spec for a profile edit component.
// 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 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/MockBuilderreturnMockBuilder(ProfileComponent,ProfileModule,).keep(ReactiveFormsModule);// // or old fashion 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// <app-root ...allInputs></profile>// and renders it.// It also respects all lifecycle hooks.// https://ng-mocks.sudo.eu/api/MockRenderconstfixture=MockRender(ProfileComponent);expect(fixture.point.componentInstance,).toEqual(assertion.any(ProfileComponent));});// A test to ensure that the component listens// on ctrl+s hotkey.it('saves on ctrl+s hot key',()=>{// A fake profile.constprofile={email: 'test2@email.com',firstName: 'testFirst2',lastName: 'testLast2',};// A spy to track save calls.// MockInstance helps to configure mock// providers, declarations and modules// before their initialization and usage.// https://ng-mocks.sudo.eu/api/MockInstanceconstspySave=MockInstance(StorageService,'save',jasmine.createSpy(),// or jest.fn());// Renders <profile [profile]="params.profile">// </profile>.// https://ng-mocks.sudo.eu/api/MockRenderconst{ point }=MockRender(ProfileComponent,{ profile },// bindings);// 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/changengMocks.change('[name=email]',// css selector'test3@em.ail',// 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/triggerngMocks.trigger(point,'keyup.control.s');// The spy should be called with the user// and the random email address.expect(spySave).toHaveBeenCalledWith({email: 'test3@em.ail',firstName: profile.firstName,lastName: profile.lastName,});});});Profit.
If you like ng-mocks, please support it:
Thank you!
P.S. Feel free to contact us if you need help.