ng-mocks
helps to:
- mock Components, Directives, Pipes, Modules, Services and Tokens
- facilitate boilerplate in tests
- access declarations via simple interface
The current version of the library has been tested and can be used with:
- Angular 12 (Jasmine, Jest, Ivy, es5, es2015)
- Angular 11 (Jasmine, Jest, Ivy, es5, es2015)
- Angular 10 (Jasmine, Jest, Ivy, es5, es2015)
- Angular 9 (Jasmine, Jest, Ivy, es5, es2015)
- Angular 8 (Jasmine, Jest, es5, es2015)
- Angular 7 (Jasmine, Jest, es5, es2015)
- Angular 6 (Jasmine, Jest, es5, es2015)
- Angular 5 (Jasmine, Jest, es5, es2015)
- Live example on StackBlitz
- Live example on CodeSandbox
Global configuration for mocks in src/test.ts
.
In case of jest src/setupJest.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-spy
ngMocks.autoSpy('jasmine'); // or jest
// ngMocks.defaultMock helps to customize
// mock declarations and providers globally.
// Here it stubs observables in AuthService.
// Therefore, we don't need to stub them every time
// in a test once we want to supress their logic.
// https://ng-mocks.sudo.eu/api/ngMocks/defaultMock
ngMocks.defaultMock(AuthService, () => ({
isLoggedIn$: EMPTY,
currentUser$: EMPTY,
}));
An example of a spec with tests.
// We are going to test AppComponent.
// Therefore, we want to mock its dependencies.
// Usually, they are declared and imported in the module
// where AppComponent has been declared too.
//
// Apart from that, we want to speed up tests,
// because TestBed will be the same for all tests
// in this suite.
describe('app-component', () => {
// Allows to use MockBuilder and MockRender
// in beforeAll and helps to avoid recreation
// of the same TestBed for every test.
// https://ng-mocks.sudo.eu/api/ngMocks/faster
ngMocks.faster();
// The next line says mock everything in AppModule,
// but keep AppComponent as it is.
beforeAll(() => {
// The result of MockBuilder should be returned.
// https://ng-mocks.sudo.eu/api/MockBuilder
return MockBuilder(AppComponent, AppModule);
});
// MockInstance helps to customize
// mock declarations and providers.
beforeEach(() => {
// A spy on a method which returns children.
// When an instance of ChildComponent is being created,
// the method will be replaced with the spy.
// https://ng-mocks.sudo.eu/api/MockInstance
MockInstance(
ChildComponent,
'list',
jasmine.createSpy(),
).and.returnValue([]);
});
it('should be created and initialized', () => {
// Creating a spy on the 'check' method of the service.
// MockInstance allows to spy / stub properties and methods
// of declarations and providers before their instances
// have been initialized.
// https://ng-mocks.sudo.eu/api/MockInstance
const spyCheck = MockInstance(
AuthService,
'check',
jasmine.createSpyObj('AuthService.check'),
).and.returnValue(true);
// MockRender creates a wrapper component with
// a template like <app-root ...allInputs></app-root>
// and renders it.
// It helps to assert lifecycle hooks.
// https://ng-mocks.sudo.eu/api/MockRender
const fixture = MockRender(AppComponent);
// Checking that the component has been created.
expect(fixture.point.componentInstance).toBeDefined();
// Checking that its ngOnInit method calls 'check' of the service.
expect(spyCheck).toHaveBeenCalled();
});
it('verifies the check user button', () => {
// A fake user data.
const user = {
id: 1,
name: 'Foo Bar',
};
// A spy on a getter property which returns user data.
// https://ng-mocks.sudo.eu/api/MockInstance
MockInstance(
AuthService,
'user',
jasmine.createSpy(),
'get',
).and.returnValue(user);
// Params for input and outputs in AppComponent.
const params = {
allowCheck: false,
user: jasmine.createSpy('user'),
};
// if AppComponent has [allowCheck] is an input and
// (user) is an output, then MockRender creates
// a wrapper component with a template like:
//
// <app-root
// [allowCheck]="params.allowCheck"
// (user)="params.user($event)"
// ></app-root>
//
// And renders it.
//
// https://ng-mocks.sudo.eu/api/MockRender
const fixture = MockRender(AppComponent, params);
// the button should be disabled with params.allowCheck = false
// https://ng-mocks.sudo.eu/api/ngMocks/find
expect(ngMocks.find('button.check').disabled).toEqual(true);
// enabling the button
params.allowCheck = true;
fixture.detectChanges();
expect(ngMocks.find('button.check').disabled).toEqual(false);
// clicking the button in order to trigger the check
// https://ng-mocks.sudo.eu/api/ngMocks/click
ngMocks.click('button.check');
// The spy in params.user should be notified about the output.
expect(params.user).toHaveBeenCalledWith({
id: 1,
name: 'Foo Bar',
});
});
});
Profit.
Please support, if you like it:
Thank you!
P.S. Feel free to contact us if you need help.