### Live example: MockHostDirective Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/guides/mock/host-directive.md This comprehensive example demonstrates mocking host directives using `TestBed`, `MockBuilder`, and `MockBuilder` with the `shallow` flag. It includes setup for `HostDirective` and `TargetComponent`. ```typescript import { Component, Directive, EventEmitter, Input, Output, } from '@angular/core'; import { TestBed } from '@angular/core/testing'; import { MockBuilder, MockDirective, MockRender, ngMocks, } from 'ng-mocks'; @Directive({ selector: 'host', standalone: true, }) class HostDirective { @Input() input?: string; @Output() output = new EventEmitter(); } @Component({ selector: 'target', hostDirectives: [ { directive: HostDirective, inputs: ['input'], outputs: ['output'], }, ], template: 'target', }) class TargetComponent { } describe('MockHostDirective', () => { describe('TestBed', () => { beforeEach(() => TestBed.configureTestingModule({ imports: [MockDirective(HostDirective)], declarations: [TargetComponent], }).compileComponents(), ); it('mocks host directives', () => { const fixture = TestBed.createComponent(TargetComponent); const directive = ngMocks.findInstance(fixture, HostDirective); expect(directive).toBeDefined(); }); }); describe('MockBuilder', () => { beforeEach(() => MockBuilder(TargetComponent, HostDirective)); it('mocks host directives', () => { MockRender(TargetComponent, { input: 'test' }); const directive = ngMocks.findInstance(HostDirective); expect(directive.input).toEqual('test'); }); }); describe('MockBuilder:shallow', () => { beforeEach(() => MockBuilder().mock(TargetComponent, { shallow: true }), ); it('mocks host directives', () => { MockRender(TargetComponent, { input: 'test' }); const directive = ngMocks.findInstance(HostDirective); expect(directive.input).toEqual('test'); }); }); }); ``` -------------------------------- ### MockBuilder: Simple Test Setup Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/api/MockBuilder.md This example demonstrates a basic setup using MockBuilder for testing a component. It highlights the use of MockBuilder and MockRender for rendering the component and asserting its content. ```typescript describe('MockBuilder:simple', () => { // Do not forget to return the promise of MockBuilder. beforeEach(() => MockBuilder(MyComponent, MyModule)); // The same as // beforeEach(() => TestBed.configureTestingModule({{ // imports: [MockModule(MyModule)], // }}).compileComponents()); // but MyComponent has not been replaced with a mock object for // the testing purposes. it('should render content ignoring all dependencies', () => { const fixture = MockRender(MyComponent); expect(fixture).toBeDefined(); expect(fixture.nativeElement.innerHTML).toContain( '
My Content
', ); }); }); ``` -------------------------------- ### Complete ngMocks.guts Example with TestBed Configuration Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/extra/quick-start.md A full example demonstrating how to use ngMocks.guts, add a sophisticated mock, and configure the TestBed within a beforeEach block. ```typescript beforeEach(() => { const testModuleDeclaration = ngMocks.guts( AppBaseComponent, // keep AppBaseModule, // mock [SearchService], // exclude ); testModuleDeclaration.providers.push({ provide: SearchService, useValue: SophisticatedMockSearchService, }); return TestBed.configureTestingModule(testModuleDeclaration); }); ``` -------------------------------- ### Full example of testing TargetPipe Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/guides/pipe.md This example demonstrates a complete test suite for an Angular pipe, including setup, rendering, and assertions for both default and parameterized behavior. ```typescript import { Pipe, PipeTransform } from '@angular/core'; import { MockBuilder, MockRender, ngMocks } from 'ng-mocks'; // A simple pipe that accepts an array of strings, sorts them, // and returns a joined string of the values. @Pipe({ name: 'target', }) class TargetPipe implements PipeTransform { public transform(value: string[], asc = true): string { const result = [...(value || [])].sort(); if (!asc) { result.reverse(); } return result.join(', '); } } describe('TestPipe', () => { ngMocks.faster(); // the same TestBed for several its. // Because we want to test the pipe, we pass it as the first // parameter of MockBuilder. We can omit the second parameter, // because there are no dependencies. // Do not forget to return the promise of MockBuilder. beforeEach(() => MockBuilder(TargetPipe)); it('sorts strings', () => { const fixture = MockRender(TargetPipe, { $implicit: ['1', '3', '2'], }); expect(fixture.nativeElement.innerHTML).toEqual('1, 2, 3'); }); it('reverses strings on param', () => { const fixture = MockRender('{{ values | target:flag }}', { flag: false, values: ['1', '3', '2'], }); expect(fixture.nativeElement.innerHTML).toEqual('3, 2, 1'); }); }); ``` -------------------------------- ### Live Example: Common Provider Test Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/guides/provider.md A complete example demonstrating how to test a common provider scenario using MockBuilder and MockRender. This setup is suitable for most provider testing needs. ```typescript import { Injectable } from '@angular/core'; import { MockBuilder, MockRender } from 'ng-mocks'; // A simple service, might have contained more logic, // but it is redundant for the test demonstration. @Injectable() class TargetService { public readonly value = true; public echo(): boolean { return this.value; } } describe('TestProviderCommon', () => { // Do not forget to return the promise of MockBuilder. beforeEach(() => MockBuilder(TargetService)); it('returns value on echo', () => { const service = MockRender(TargetService).point.componentInstance; expect(service.echo()).toEqual(service.value); }); }); ``` -------------------------------- ### Full Example: Testing Standalone Directive Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/guides/directive-standalone.md A complete example demonstrating how to test a standalone directive, including mocking a root service and asserting method calls. ```typescript import { Directive, Injectable, Input, OnInit, } from '@angular/core'; import { MockBuilder, MockRender, ngMocks } from 'ng-mocks'; // A root service we want to mock. @Injectable({ providedIn: 'root', }) class RootService { trigger(name: string | null) { // does something very cool return name; } } // A standalone directive we are going to test. @Directive({ selector: 'standalone', standalone: true, }) class StandaloneDirective implements OnInit { @Input() public readonly name: string | null = null; constructor(public readonly rootService: RootService) {} ngOnInit(): void { this.rootService.trigger(this.name); } } describe('TestStandaloneDirective', () => { beforeEach(() => { return MockBuilder(StandaloneDirective); }); it('renders dependencies', () => { // Rendering the directive. MockRender(StandaloneDirective, { name: 'test', }); // Asserting that StandaloneDirective calls RootService.trigger. const rootService = ngMocks.findInstance(RootService); // it's possible because of autoSpy. expect(rootService.trigger).toHaveBeenCalledWith('test'); }); }); ``` -------------------------------- ### Full Example: Testing a Structural Directive Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/guides/directive-structural.md This comprehensive example demonstrates testing a custom structural directive. It covers setup with `MockBuilder`, rendering with `MockRender`, and asserting the directive's behavior by toggling its input and checking DOM content. ```typescript import { Directive, Input, TemplateRef, ViewContainerRef, } from '@angular/core'; import { MockBuilder, MockRender } from 'ng-mocks'; // This directive is the same as `ngIf`, // it renders its content only when its input has truly value. @Directive({ selector: '[target]', }) class TargetDirective { public constructor( protected templateRef: TemplateRef, protected viewContainerRef: ViewContainerRef, ) {} @Input() public set target(value: any) { if (value) { this.viewContainerRef.createEmbeddedView(this.templateRef); } else { this.viewContainerRef.clear(); } } } describe('TestStructuralDirectiveWithoutContext', () => { // Because we want to test the directive, we pass it as the first // parameter of MockBuilder. We can omit the second parameter, // because there are no dependencies. // Do not forget to return the promise of MockBuilder. beforeEach(() => MockBuilder(TargetDirective)); it('hides and renders its content', () => { const fixture = MockRender( `
content
`, { value: false, }, ); // Because the value is false the "content" should not be // rendered. expect(fixture.nativeElement.innerHTML).not.toContain('content'); // Let's change the value to true and assert that the "content" // has been rendered. fixture.componentInstance.value = true; fixture.detectChanges(); expect(fixture.nativeElement.innerHTML).toContain('content'); // Let's change the value to false and assert that the // "content" has been hidden. fixture.componentInstance.value = false; fixture.detectChanges(); expect(fixture.nativeElement.innerHTML).not.toContain('content'); }); }); ``` -------------------------------- ### Install Dependencies with Docker Compose Source: https://github.com/help-me-mom/ng-mocks/blob/main/CONTRIBUTING.md Execute this command in a bash session to install all necessary development dependencies using Docker Compose. Ensure Docker is running. ```shell sh ./compose.sh ``` -------------------------------- ### Advanced MockRender Example Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/api/MockRender.md An in-depth example demonstrating how to render a custom template and interact with component inputs and outputs using ngMocks helpers. ```APIDOC ## Advanced MockRender Example ### Description This example showcases advanced usage of `MockRender` for testing component interactions, including input binding, output emission, and template content. ### Method `MockRender(template: string, data?: object, options?: object): ComponentFixture` ### Parameters - **template** (string) - Required - The HTML template string for the component, including event bindings and content projection. - **data** (object) - Required - An object mapping event handler names to spy functions and input names to their values. ### Request Example ```ts describe('MockRender', () => { beforeEach(() => MockBuilder(TargetComponent, ChildModule)); it('renders template', () => { const spy = jasmine.createSpy(); const fixture = MockRender( ` something as ng-template something as ng-content `, { myListener1: spy, myParam1: 'something1', } ); expect(ngMocks.input(fixture.point, 'value1')).toEqual('something1'); expect(ngMocks.input(fixture.point, 'value2')).toEqual('check'); ngMocks.output(fixture.point, 'trigger').emit('foo1'); expect(spy).toHaveBeenCalledWith('foo1'); }); it('renders inputs and outputs automatically', () => { const spy = jasmine.createSpy(); const fixture = MockRender(TargetComponent, { trigger: spy, value1: 'something2', }); expect(ngMocks.input(fixture.point, 'value1')).toEqual('something2'); expect(ngMocks.input(fixture.point, 'value2')).toEqual('default2'); ngMocks.output(fixture.point, 'trigger').emit('foo2'); expect(spy).toHaveBeenCalledWith('foo2'); fixture.componentInstance.value1 = 'updated'; fixture.detectChanges(); expect(ngMocks.input(fixture.point, 'value1')).toEqual('updated'); }); }); ``` ### Notes - Remember to call `fixture.detectChanges()` and/or `await fixture.whenStable()` after updating component properties to ensure the render is updated. - `ngMocks.input` and `ngMocks.output` are helper functions to access component inputs and outputs respectively. ``` -------------------------------- ### Full Example: Testing an HTTP Interceptor Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/guides/http-interceptor.md A complete test case demonstrating the setup and execution of an HTTP interceptor test. Includes the interceptor definition, module, and the test suite. ```typescript import { HTTP_INTERCEPTORS, HttpClient, HttpClientModule, HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, } from '@angular/common/http'; import { HttpClientTestingModule, HttpTestingController, } from '@angular/common/http/testing'; import { Injectable, NgModule } from '@angular/core'; import { Observable } from 'rxjs'; import { MockBuilder, MockRender, NG_MOCKS_INTERCEPTORS, ngMocks, } from 'ng-mocks'; // An interceptor we want to test. @Injectable() class TargetInterceptor implements HttpInterceptor { protected value = 'HttpInterceptor'; public intercept( request: HttpRequest, next: HttpHandler, ): Observable> { return next.handle( request.clone({ setHeaders: { 'My-Custom': this.value, }, }), ); } } // An interceptor we want to ignore. @Injectable() class MockInterceptor implements HttpInterceptor { protected value = 'Ignore'; public intercept( request: HttpRequest, next: HttpHandler, ): Observable> { return next.handle( request.clone({ setHeaders: { 'My-Mock': this.value, }, }), ); } } // A module with its definition. @NgModule({ imports: [HttpClientModule], providers: [ TargetInterceptor, MockInterceptor, { multi: true, provide: HTTP_INTERCEPTORS, useExisting: TargetInterceptor, }, { multi: true, provide: HTTP_INTERCEPTORS, useClass: MockInterceptor, }, ], }) class TargetModule {} describe('TestHttpInterceptor', () => { // Because we want to test the interceptor, we pass it as the first // parameter of MockBuilder. To correctly satisfy its dependencies // we need to pass its module as the second parameter. Also we // should to pass HTTP_INTERCEPTORS into `.mock` and replace // HttpClientModule with HttpClientTestingModule. beforeEach(() => MockBuilder(TargetInterceptor, TargetModule) .exclude(NG_MOCKS_INTERCEPTORS) .keep(HTTP_INTERCEPTORS) .replace(HttpClientModule, HttpClientTestingModule), ); it('triggers interceptor', () => { MockRender(); // Let's extract the service and http controller for testing. const client = ngMocks.findInstance(HttpClient); const httpMock = ngMocks.findInstance(HttpTestingController); // Let's do a simple request. client.get('/target').subscribe(); // Now we can assert that a header has been added to the request. const req = httpMock.expectOne('/target'); req.flush(''); httpMock.verify(); expect(req.request.headers.get('My-Custom')).toEqual( 'HttpInterceptor', ); }); }); ``` -------------------------------- ### Standard TestBed Configuration Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/api/MockProvider.md This is a typical setup for an Angular testbed before introducing mock providers. It includes the component and its dependencies. ```typescript describe('Test', () => { let component: TargetComponent; let fixture: ComponentFixture; beforeEach(() => { TestBed.configureTestingModule({ declarations: [TargetComponent], providers: [ // Annoying dependencies. DependencyService, ObservableService, ], }); fixture = TestBed.createComponent(TargetComponent); component = fixture.componentInstance; }); }); ``` -------------------------------- ### Full Example: Testing Structural Directive with Context Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/guides/directive-structural-context.md A complete test case demonstrating the setup and assertion for a custom structural directive with context variables. Includes directive definition, MockBuilder setup, and rendering assertions. ```typescript import { Directive, Input, TemplateRef, ViewContainerRef, } from '@angular/core'; import { MockBuilder, MockRender } from 'ng-mocks'; interface ITargetContext { $implicit: string; myIndex: number; } // This directive is almost the same as `ngFor`, // it renders every item as a new row. @Directive({ selector: '[target]', }) class TargetDirective { public constructor( protected templateRef: TemplateRef, protected viewContainerRef: ViewContainerRef, ) {} @Input() public set target(items: string[]) { this.viewContainerRef.clear(); for (let index = 0; index < items.length; index += 1) { const value = items[index]; this.viewContainerRef.createEmbeddedView(this.templateRef, { $implicit: value, myIndex: index, }); } } } describe('TestStructuralDirectiveWithContext', () => { // Because we want to test the directive, we pass it as the first // parameter of MockBuilder. We can omit the second parameter, // because there are no dependencies. // Do not forget to return the promise of MockBuilder. beforeEach(() => MockBuilder(TargetDirective)); it('renders passed values', () => { const fixture = MockRender( `
{{index}}: {{ value }}
`, { values: ['hello', 'world'], }, ); // Let's assert that the 'values' have been rendered as expected expect(fixture.nativeElement.innerHTML).toContain('0: hello'); expect(fixture.nativeElement.innerHTML).toContain('1: world'); // Let's change the 'values' and assert that the new render // has done everything as expected. fixture.componentInstance.values = ['ngMocks']; fixture.detectChanges(); expect(fixture.nativeElement.innerHTML).toContain('0: ngMocks'); expect(fixture.nativeElement.innerHTML).not.toContain('0: hello'); expect(fixture.nativeElement.innerHTML).not.toContain('1: world'); }); }); ``` -------------------------------- ### Angular Component Test Setup with Spies Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/extra/how-to-write-tests.md Demonstrates a typical Angular component test setup including TestBed configuration, component instantiation, and service spy setup. This approach can lead to significant boilerplate with multiple spies and services. ```typescript describe('BannerComponent', () => { let component: BannerComponent; let fixture: ComponentFixture; // added for spies let userService: UserService; let userSaveSpy: Spy; beforeEach(waitForAsync(() => { TestBed.configureTestingModule({ declarations: [BannerComponent], providers: [UserService], }).compileComponents(); })); beforeEach(() => { fixture = TestBed.createComponent(BannerComponent); component = fixture.componentInstance; // some spies userService = TestBed.inject(UserService); userSaveSpy = spyOn(userService, 'save'); fixture.detectChanges(); }); it('should create', () => { expect(component).toBeDefined(); }); }); ``` -------------------------------- ### Full Example: Testing Directive Provider with ng-mocks Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/guides/directive-provider.md This comprehensive example demonstrates how to test a service provided by an Angular directive using ng-mocks. It includes setup, rendering, and assertion of the service's behavior. ```typescript import { Directive, ElementRef, Injectable, OnInit, TemplateRef, ViewContainerRef, } from '@angular/core'; import { MockBuilder, MockRender, ngMocks } from 'ng-mocks'; // A simple service, might have contained more logic, // but it is redundant for the test demonstration. @Injectable() class TargetService { public readonly value = true; } // The purpose of the directive is to add a background color // on mouseenter and to remove it on mouseleave. @Directive({ providers: [TargetService], selector: '[target]', }) class TargetDirective implements OnInit { public constructor( public readonly service: TargetService, protected ref: ElementRef, protected templateRef: TemplateRef, protected viewContainerRef: ViewContainerRef, ) {} public ngOnInit(): void { this.viewContainerRef.clear(); if (this.service.value) { this.viewContainerRef.createEmbeddedView(this.templateRef); } } } describe('TestProviderInDirective', () => { ngMocks.faster(); // the same TestBed for several its. // Because we want to test the service, we pass it as the first // parameter of MockBuilder. // Because we do not care about TargetDirective, we pass it as // the second parameter for being replaced with a mock copy. // Do not forget to return the promise of MockBuilder. beforeEach(() => MockBuilder(TargetService, TargetDirective)); it('has access to the service via a directive', () => { // Let's render a div with the directive. MockRender('
'); // Let's find the debugElement with the directive. // Please note, that we use ngMocks.find here. const el = ngMocks.find(TargetDirective); // Let's extract the service. const service = ngMocks.get(el, TargetService); // Here we go, now we can assert everything about the service. expect(service.value).toEqual(true); }); it('has access to the service via a structural directive', () => { // Let's render a div with the directive. MockRender('
'); // Let's find the debugNode with the directive. // Please note, that we use ngMocks.reveal here. const node = ngMocks.reveal(TargetDirective); // Let's extract the service. const service = ngMocks.get(node, TargetService); // Here we go, now we can assert everything about the service. expect(service.value).toEqual(true); }); }); ``` -------------------------------- ### Full Example: Testing an HTTP Request in Angular Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/guides/http-request.md This comprehensive example demonstrates setting up `MockBuilder`, replacing `HttpClientModule`, subscribing to a service method, mocking an HTTP request with `HttpTestingController`, flushing a response, and asserting the final result. ```typescript import { HttpClient, HttpClientModule } from '@angular/common/http'; import { HttpClientTestingModule, HttpTestingController, } from '@angular/common/http/testing'; import { Injectable, NgModule } from '@angular/core'; import { Observable } from 'rxjs'; import { MockBuilder, MockRender, ngMocks } from 'ng-mocks'; // A service that does http requests. @Injectable() class TargetService { public constructor(protected http: HttpClient) {} public fetch(): Observable { return this.http.get('/data'); } } // A module providing the service and http client. @NgModule({ imports: [HttpClientModule], providers: [TargetService], }) class TargetModule {} describe('TestHttpRequest', () => { // Because we want to test the service, we pass it as the first // parameter of MockBuilder. To correctly satisfy its // initialization, we need to pass its module as the second // parameter. And, the last but not the least, we need to replace // HttpClientModule with HttpClientTestingModule. beforeEach(() => MockBuilder(TargetService, TargetModule).replace( HttpClientModule, HttpClientTestingModule, ), ); it('sends a request', () => { MockRender(); // Let's extract the service and http controller for testing. const service = ngMocks.findInstance(TargetService); const httpMock = ngMocks.findInstance(HttpTestingController); // A simple subscription to check what the service returns. let actual: any; service.fetch().subscribe(value => (actual = value)); // Simulating a request. const req = httpMock.expectOne('/data'); expect(req.request.method).toEqual('GET'); req.flush([false, true, false]); httpMock.verify(); // Asserting the result. expect(actual).toEqual([false, true, false]); }); }); ``` -------------------------------- ### Full Example: Mocking Structural Directive (let, of) - Static Context Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/guides/mock/directive-structural-let-of.md A complete test case demonstrating how to mock a structural directive with `let` and `of` syntax using static context. It includes the directive definition and the test setup. ```typescript import { Directive, Input, TemplateRef, ViewContainerRef, } from '@angular/core'; import { MockBuilder, MockRender, ngMocks } from 'ng-mocks'; @Directive({ selector: '[dxTemplate]', }) class DxTemplateDirective { @Input() public readonly dxTemplateOf: string | null = null; public constructor( protected templateRef: TemplateRef, protected viewContainerRef: ViewContainerRef, ) {} } describe('TestDirectiveLetOf:static', () => { beforeEach(() => MockBuilder().mock(DxTemplateDirective, { // We should not only render the structural directive, // but also provide its context variables. render: { $implicit: { data: 'MOCK_DATA', }, }, }), ); it('renders a mock of structural directives', () => { const fixture = MockRender( `
{{ cellTemplate.data }}
`, ); // firstly, let's check that we passed 'actionsCellTemplate' as input value. expect( ngMocks.findInstance(DxTemplateDirective).dxTemplateOf, ).toEqual('actionsCellTemplate'); // secondly, let's check that MOCK_DATA has been rendered. expect(ngMocks.formatHtml(fixture)).toEqual( '
MOCK_DATA
', ); }); }); ``` -------------------------------- ### Example of Constructor Initialization Logic Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/guides/mock/initialization-logic.md Illustrates how a component's property is calculated in the constructor based on injected dependencies like configuration and user services. ```typescript class TargetComponent { // A property which will be used somewhere else: in a template or wherever. public name: string; // Required dependencies. constructor( @Inject(CONFIG) config: ConfigInterface, user: CurrentUserService, ) { // Business logic in the constructor to calculate the name. if (config.displayName === 'first') { this.name = user.firstName; } else { this.name = user.lastName; } } } ``` -------------------------------- ### Standard Angular TestBed Test Example Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/extra/how-to-write-tests.md An example of a test suite using Angular's TestBed to configure the testing module, create component fixtures, and perform assertions. This structure ensures each test is self-sufficient. ```typescript describe('BannerComponent', () => { beforeEach(waitForAsync(() => { // 1. configuring TestBed for all tests in the suite TestBed.configureTestingModule({ declarations: [BannerComponent], providers: [UserService], }).compileComponents(); })); it('should create', () => { // 2. customizing mocks, configuring inputs, etc // nothing to do // 3. creating a fixture const fixture = TestBed.createComponent(BannerComponent); fixture.detectChanges(); // 4. asserting expectations expect(fixture.componentInstance).toBeDefined(); }); it('should do something with a service', () => { // 2. customizing mocks, configuring inputs, etc const userService = TestBed.inject(UserService); const userSaveSpy = spyOn(userService, 'save'); // 3. creating a fixture const fixture = TestBed.createComponent(BannerComponent); const component = fixture.componentInstance; component.action = 'save-user'; fixture.detectChanges(); // 4. asserting expectations expect(userSaveSpy).toHaveBeenCalled(); }); }); ``` -------------------------------- ### Test provider with useExisting Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/guides/provider.md Demonstrates how to test a service that is provided using `useExisting`. This example shows how to mock dependencies and verify the correct service is injected. ```typescript import { Injectable, NgModule } from '@angular/core'; import { MockBuilder, MockInstance, MockRender, MockReset, } from 'ng-mocks'; // A service we want to use. @Injectable() class Service1 { public name = 'target'; } // A service we want to replace. @Injectable() class Service2 { public name = 'target'; } // A service we want to test and to replace via useExisting. @Injectable() class TargetService {} // A module that provides all services. @NgModule({ providers: [ Service1, { provide: Service2, useExisting: Service1, }, { provide: TargetService, useExisting: Service2, }, ], }) class TargetModule {} describe('TestProviderWithUseExisting', () => { // Because we want to test the service, we pass it as the first // parameter of MockBuilder. To correctly satisfy its initialization // we need to pass its module as the second parameter. // Do not forget to return the promise of MockBuilder. beforeEach(() => MockBuilder(TargetService, TargetModule)); beforeAll(() => { // Let's customize a bit behavior of the mock copy of Service1. MockInstance(Service2, { init: instance => { instance.name = 'mock2'; }, }); }); // Resets customizations from MockInstance. afterAll(MockReset); it('creates TargetService', () => { const service = MockRender< TargetService & Partial<{ name: string }> >(TargetService).point.componentInstance; // Because Service2 has been replaced with a mock copy, // we are getting here a mock copy of Service2 instead of Service1. expect(service).toEqual(jasmine.any(Service2)); // Because we have kept TargetService we are getting here a // mock copy of Service2 as it says in useExisting. expect(service.name).toEqual('mock2'); }); }); ``` -------------------------------- ### Full Example: Testing Various Token Types with ng-mocks Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/guides/token.md This comprehensive example demonstrates testing different types of tokens: `useClass`, `useExisting`, `useFactory`, and `useValue`. It includes setting up the `TargetModule` with all necessary providers and using `MockBuilder` to prepare the testing environment. Assertions verify the correct instantiation and values for each token type. ```typescript import { Injectable, InjectionToken, NgModule } from '@angular/core'; import { MockBuilder, MockRender, ngMocks } from 'ng-mocks'; const TOKEN_CLASS = new InjectionToken('CLASS'); const TOKEN_EXISTING = new InjectionToken('EXISTING'); const TOKEN_FACTORY = new InjectionToken('FACTORY'); const TOKEN_VALUE = new InjectionToken('VALUE'); class ServiceClass { public readonly name = 'class'; } @Injectable() class ServiceExisting { public readonly name = 'existing'; } // A module that provides all services. @NgModule({ providers: [ ServiceExisting, { provide: TOKEN_CLASS, useClass: ServiceClass, }, { provide: TOKEN_EXISTING, useExisting: ServiceExisting, }, { provide: TOKEN_FACTORY, useFactory: () => 'FACTORY', }, { provide: TOKEN_VALUE, useValue: 'VALUE', }, ], }) class TargetModule {} describe('TestToken', () => { ngMocks.faster(); // Because we want to test the tokens, we pass them in .keep in // the chain on MockBuilder. To correctly satisfy their // initialization we need to pass its module as the second // parameter. beforeEach(() => { return MockBuilder( [TOKEN_CLASS, TOKEN_EXISTING, TOKEN_FACTORY, TOKEN_VALUE], TargetModule, ); }); it('creates TOKEN_CLASS', () => { const token = MockRender(TOKEN_CLASS).point.componentInstance; // Verifying that the token is an instance of ServiceClass. expect(token).toEqual(jasmine.any(ServiceClass)); expect(token.name).toEqual('class'); }); it('creates TOKEN_EXISTING', () => { const token = MockRender(TOKEN_EXISTING).point .componentInstance; // Verifying that the token is an instance of ServiceExisting. // But because it has been replaced with a mock copy, // we should see an empty name. expect(token).toEqual(jasmine.any(ServiceExisting)); expect(token.name).toBeUndefined(); }); it('creates TOKEN_FACTORY', () => { const token = MockRender(TOKEN_FACTORY).point.componentInstance; // Checking that we have here what factory has been created. expect(token).toEqual('FACTORY'); }); it('creates TOKEN_VALUE', () => { const token = MockRender(TOKEN_VALUE).point.componentInstance; // Checking the set value. expect(token).toEqual('VALUE'); }); }); ``` -------------------------------- ### MockRender Examples Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/api/MockRender.md Provides various examples of using MockRender with different types of Angular entities like components, directives, pipes, services, and tokens. ```APIDOC ## MockRender Examples ### Component ```ts const fixture = MockRender(AppComponent); // Access the wrapper component instance // fixture.componentInstance; // Access the tested component instance // fixture.point.componentInstance; ``` ### Directive ```ts const fixture = MockRender(AppDirective); // Access the wrapper component instance // fixture.componentInstance; // Access the tested directive instance // fixture.point.componentInstance; ``` ### Pipe ```ts const fixture = MockRender(DatePipe, { $implicit: new Date(), // The value to transform }); // Access the wrapper component instance, which manages params // fixture.componentInstance.$implicit.setHours(5); // Access the tested pipe instance // fixture.point.componentInstance; ``` ### Template String ```ts const fixture = MockRender('{{ 3.99 | currency }}'); // Access the wrapper component instance // fixture.point.componentInstance; // Unknown instance ``` ### Service ```ts const fixture = MockRender(TranslationService); // Access the wrapper component instance // fixture.componentInstance; // Access the tested service instance // fixture.point.componentInstance; ``` ### Token ```ts const fixture = MockRender(APP_BASE_HREF); // Access the wrapper component instance // fixture.componentInstance; // Access the value of the token // fixture.point.componentInstance; ``` ``` -------------------------------- ### Full Example: Testing an Attribute Directive Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/guides/directive-attribute.md A comprehensive example demonstrating how to test an Angular attribute directive. It includes setting up the mock, rendering the template, simulating events, and asserting DOM changes and input property effects. ```typescript import { Directive, ElementRef, HostListener, Input, } from '@angular/core'; import { MockBuilder, MockRender, ngMocks } from 'ng-mocks'; // The purpose of the directive is to add a background color // on mouseenter and to remove it on mouseleave. // By default the color is yellow. @Directive({ selector: '[target]', }) class TargetDirective { @Input() public color = 'yellow'; public constructor(protected ref: ElementRef) {} @HostListener('mouseenter') public onMouseEnter() { this.ref.nativeElement.style.backgroundColor = this.color; } @HostListener('mouseleave') public onMouseLeave() { this.ref.nativeElement.style.backgroundColor = ''; } } describe('TestAttributeDirective', () => { ngMocks.faster(); // the same TestBed for several its. // Because we want to test the directive, we pass it as the first // parameter of MockBuilder. We can omit the second parameter, // because there are no dependencies. // Do not forget to return the promise of MockBuilder. beforeEach(() => MockBuilder(TargetDirective)); it('uses default background color', () => { const fixture = MockRender('
'); // By default, without the mouse enter, there is no background // color on the div. expect(fixture.nativeElement.innerHTML).not.toContain( 'style="background-color: yellow;"', ); // Let's simulate the mouse enter event. // fixture.point is out root element from the rendered template, // therefore it points to the div we want to trigger the event // on. fixture.point.triggerEventHandler('mouseenter', null); // Let's assert the color. expect(fixture.nativeElement.innerHTML).toContain( 'style="background-color: yellow;"', ); // Now let's simulate the mouse leave event. fixture.point.triggerEventHandler('mouseleave', null); // And assert that the background color is gone now. expect(fixture.nativeElement.innerHTML).not.toContain( 'style="background-color: yellow;"', ); }); it('sets provided background color', () => { // When we want to test inputs / outputs we need to use the second // parameter of MockRender, simply pass there variables for the // template, they'll become properties of // fixture.componentInstance. const fixture = MockRender('
', { color: 'red', }); // Let's assert that the background color is red. fixture.point.triggerEventHandler('mouseenter', null); expect(fixture.nativeElement.innerHTML).toContain( 'style="background-color: red;"', ); // Let's switch the color, we do not need ".point", because we // access a middle component of MockRender. fixture.componentInstance.color = 'blue'; fixture.detectChanges(); // shaking the template fixture.point.triggerEventHandler('mouseenter', null); expect(fixture.nativeElement.innerHTML).toContain( 'style="background-color: blue;"', ); }); }); ``` -------------------------------- ### Live Example: Mocking ActivatedRoute in Angular Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/guides/mock/activated-route.md This comprehensive example demonstrates how to mock ActivatedRoute, including its snapshot and paramMap, within an Angular test environment using ng-mocks. It sets up the mock for a component that retrieves a route parameter. ```typescript import { Component, NgModule, OnInit } from '@angular/core'; import { ActivatedRoute, RouterModule } from '@angular/router'; import { MockBuilder, MockInstance, MockRender } from 'ng-mocks'; @Component({ selector: 'route', template: '{{ param }}', }) class RouteComponent implements OnInit { public param: string | null = null; public constructor(private route: ActivatedRoute) {} ngOnInit() { this.param = this.route.snapshot.paramMap.get('paramId'); } } @NgModule({ declarations: [RouteComponent], imports: [ RouterModule.forRoot([ { path: 'test/:paramId', component: RouteComponent, }, ]), ], }) class TargetModule {} describe('MockActivatedRoute', () => { // Resets customizations after each test, in our case of `ActivatedRoute`. MockInstance.scope(); // Keeping RouteComponent as it is and mocking all declarations in TargetModule. beforeEach(() => MockBuilder(RouteComponent, TargetModule)); it('uses paramId from ActivatedRoute', () => { // Let's set the params of the snapshot. MockInstance( ActivatedRoute, 'snapshot', jasmine.createSpy(), 'get', ).and.returnValue({ paramMap: new Map([['paramId', 'paramValue']]), }); // in case of jest // MockInstance( // ActivatedRoute, // 'snapshot', // jest.fn(), // 'get', // ).mockReturnValue({ // paramMap: new Map([['paramId', 'paramValue']]), // }); // Rendering RouteComponent. const fixture = MockRender(RouteComponent); // Asserting it got the right paramId. expect(fixture.point.componentInstance.param).toEqual( 'paramValue', ); }); }); ``` -------------------------------- ### Using MockBuilder and MockRender Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/api/MockComponent.md Leverage MockBuilder for setting up the testing module and MockRender for rendering the component under test, simplifying mock component setup. ```typescript describe('Test', () => { beforeEach(() => { // DependencyComponent is a declaration or imported somewhere in ItsModule. return MockBuilder(TargetComponent, ItsModule); }); it('should create', () => { const fixture = MockRender(TargetComponent); expect(fixture.point.componentInstance).toBeDefined(); }); }); ``` -------------------------------- ### Python Syntax Highlighting Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/style-guide.md Example of Python code block with syntax highlighting. ```python s = "Python syntax highlighting" print(s) ``` -------------------------------- ### MockRender Example with AppComponent Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/api/MockRender.md Renders an AppComponent. `fixture.componentInstance` refers to a middle component, while `fixture.point.componentInstance` is the actual AppComponent instance. ```typescript const fixture = MockRender(AppComponent); // is a middle component, mostly useless fixture.componentInstance; // an instance of the AppComponent fixture.point.componentInstance; ``` -------------------------------- ### Full Example: Testing Host Directive Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/guides/host-directive.md A complete test case demonstrating how to mock a component and test its host directive using `ng-mocks`. ```typescript import { Component, Directive, HostBinding, Input, } from '@angular/core'; import { MockBuilder, MockRender, ngMocks } from 'ng-mocks'; @Directive({ selector: 'host', standalone: true, }) class HostDirective { @HostBinding('attr.name') @Input() input?: string; } @Component({ selector: 'target', hostDirectives: [ { directive: HostDirective, inputs: ['input'], }, ], template: 'target', }) class TargetComponent { } describe('TestHostDirective', () => { beforeEach(() => MockBuilder(HostDirective, TargetComponent)); it('keeps host directives', () => { const fixture = MockRender(TargetComponent, { input: 'test' }); const directive = ngMocks.findInstance(HostDirective); expect(directive.input).toEqual('test'); expect(ngMocks.formatHtml(fixture)).toContain(' name="test"'); }); }); ``` -------------------------------- ### MockRender Example with TranslationService Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/api/MockRender.md Renders a TranslationService. `fixture.componentInstance` refers to a middle component, while `fixture.point.componentInstance` is the actual TranslationService instance. ```typescript const fixture = MockRender(TranslationService); // is a middle component, mostly useless fixture.componentInstance; // an instance of TranslationService fixture.point.componentInstance; ``` -------------------------------- ### MockRender Example with Template String Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/api/MockRender.md Renders a template string, such as a string with a pipe. `fixture.point.componentInstance` will be an unknown instance in this case. ```typescript const fixture = MockRender('{{ 3.99 | currency }}'); // an unknown instance fixture.point.componentInstance; ``` -------------------------------- ### MockRender Example with APP_BASE_HREF Token Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/api/MockRender.md Renders a token like APP_BASE_HREF. `fixture.componentInstance` refers to a middle component, while `fixture.point.componentInstance` is the value of the token. ```typescript const fixture = MockRender(APP_BASE_HREF); // is a middle component, mostly useless fixture.componentInstance; // a value of APP_BASE_HREF fixture.point.componentInstance; ``` -------------------------------- ### MockRender Example with AppDirective Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/api/MockRender.md Renders an AppDirective. `fixture.componentInstance` refers to a middle component, while `fixture.point.componentInstance` is the actual AppDirective instance. ```typescript const fixture = MockRender(AppDirective); // is a middle component, mostly useless fixture.componentInstance; // an instance of AppDirective fixture.point.componentInstance; ``` -------------------------------- ### Configure Jest setupFilesAfterEnv in angular.json Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/extra/install.md Configure Jest to use a custom setup file for ng-mocks by adding 'setupFilesAfterEnv' to your angular.json configuration. ```json "test": { "builder": "@angular-builders/jest:run", "options": { "setupFilesAfterEnv": "./src/setup-jest.ts" // <-- this is the fix } } ``` -------------------------------- ### Stubbing multiple methods Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/api/ngMocks/stub.md This example demonstrates how to stub multiple methods of a service instance simultaneously. This is useful for setting up multiple mock behaviors at once. ```APIDOC ## ngMocks.stub(service, methods) ### Description Stubs multiple methods of a service instance. ### Method Signature `ngMocks.stub(service: any, methods: string[]): void` ### Parameters - **service** (any) - The service instance to stub. - **methods** (string[]) - An array of method names to stub. ``` -------------------------------- ### Advanced MockRender Example Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/api/MockRender.md Demonstrates rendering a component with complex inputs, outputs, and ng-templates. Use ngMocks.input and ngMocks.output to interact with component properties and events. ```typescript describe('MockRender', () => { // Do not forget to return the promise of MockBuilder. beforeEach(() => MockBuilder(TargetComponent, ChildModule)); it('renders template', () => { const spy = jasmine.createSpy(); // in case of jest // const spy = jest.fn(); const fixture = MockRender( ` something as ng-template something as ng-content `, { myListener1: spy, myParam1: 'something1', }, ); // ngMocks.input helps to get the current value of an input on // a related debugElement without knowing its owner. expect(ngMocks.input(fixture.point, 'value1')).toEqual( 'something1', ); expect(ngMocks.input(fixture.point, 'value2')).toEqual('check'); // ngMocks.output does the same with outputs. ngMocks.output(fixture.point, 'trigger').emit('foo1'); expect(spy).toHaveBeenCalledWith('foo1'); }); it('renders inputs and outputs automatically', () => { const spy = jasmine.createSpy(); // in case of jest // const logoClickSpy = jest.fn(); // Generates a template like: // . const fixture = MockRender(TargetComponent, { trigger: spy, value1: 'something2', }); // Checking the inputs. expect(ngMocks.input(fixture.point, 'value1')).toEqual( 'something2', ); expect(ngMocks.input(fixture.point, 'value2')).toEqual( 'default2', ); // Checking the outputs. ngMocks.output(fixture.point, 'trigger').emit('foo2'); expect(spy).toHaveBeenCalledWith('foo2'); // checking that an updated value has been passed into // the testing component. fixture.componentInstance.value1 = 'updated'; fixture.detectChanges(); expect(ngMocks.input(fixture.point, 'value1')).toEqual('updated'); }); }); ``` -------------------------------- ### Overriding properties and methods Source: https://github.com/help-me-mom/ng-mocks/blob/main/docs/articles/api/ngMocks/stub.md This example shows how to override existing properties and methods of a service instance by providing an object with new values or spies. ```APIDOC ## ngMocks.stub(instance, overrides) ### Description Overrides properties and methods of an instance with provided values or spies. ### Method Signature `ngMocks.stub(instance: any, overrides: { [key: string]: any }): void` ### Parameters - **instance** (any) - The instance whose properties and methods are to be overridden. - **overrides** ({ [key: string]: any }) - An object where keys are property/method names and values are the new values or spies. ```