Click to see a detailed information
+
+
+```typescript
+import { MockBuilder } from 'ng-mocks';
+
+// Mocks everything in MyModule (imports, declarations, providers)
+// but keeps MyComponent as it is.
+const ngModule = MockBuilder(MyComponent, MyModule).build();
+
+// The same as code above.
+const ngModule = MockBuilder().keep(MyComponent, { export: true }).mock(MyModule).build();
+
+// If we want to keep a module, component, directive, pipe or provider as it is (not mocking).
+// We should use .keep.
+const ngModule = MockBuilder(MyComponent, MyModule)
+ .keep(SomeModule)
+ .keep(SomeComponent)
+ .keep(SomeDirective)
+ .keep(SomePipe)
+ .keep(SomeDependency)
+ .keep(SomeInjectionToken)
+ .build();
+// If we want to mock something, even a part of a kept module we should use .mock.
+const ngModule = MockBuilder(MyComponent, MyModule)
+ .mock(SomeModule)
+ .mock(SomeComponent)
+ .mock(SomeDirective)
+ .mock(SomePipe)
+ .mock(SomeDependency)
+ .mock(SomeInjectionToken)
+ .build();
+// If we want to replace something with something we should use .replace.
+// The replacement has to be decorated with the same decorator as the source.
+// It's impossible to replace a provider or a service, we should use .provide or .mock for that.
+const ngModule = MockBuilder(MyComponent, MyModule)
+ .replace(HttpClientModule, HttpClientTestingModule)
+ .replace(SomeComponent, SomeOtherComponent)
+ .replace(SomeDirective, SomeOtherDirective)
+ .replace(SomePipe, SomeOtherPipe)
+ .build();
+// For pipes we can set its handler as the 2nd parameter of .mock too.
+const ngModule = MockBuilder(MyComponent, MyModule)
+ .mock(SomePipe, value => 'My Custom Content')
+ .build();
+// If we want to add or replace a provider or a service we should use .provide.
+// It has the same interface as a regular provider.
+const ngModule = MockBuilder(MyComponent, MyModule)
+ .provide(MyService)
+ .provide([SomeService1, SomeService2])
+ .provide({ provide: SomeComponent3, useValue: anything1 })
+ .provide({ provide: SOME_TOKEN, useFactory: () => anything2 })
+ .build();
+// If we need to mock, or to use useValue we can use .mock for that.
+const ngModule = MockBuilder(MyComponent, MyModule)
+ .mock(MyService)
+ .mock(SomeService1)
+ .mock(SomeService2)
+ .mock(SomeComponent3, anything1)
+ .mock(SOME_TOKEN, anything2)
+ .build();
+// Anytime we can change our decision.
+// The last action on the same object wins.
+const ngModule = MockBuilder(MyComponent, MyModule)
+ .keep(SomeModule)
+ .mock(SomeModule)
+ .keep(SomeModule)
+ .mock(SomeModule)
+ .build();
+// If we want to test a component, directive or pipe which wasn't exported
+// we should mark it as an 'export'.
+// Doesn't matter how deep it is. It will be exported to the level of TestingModule.
+const ngModule = MockBuilder(MyComponent, MyModule)
+ .keep(SomeModuleComponentDirectivePipeProvider1, {
+ export: true,
+ })
+ .build();
+// By default all definitions (kept and mocked) are added to the TestingModule
+// if they are not dependency of another definition.
+// Modules are added as imports to the TestingModule.
+// Components, Directive, Pipes are added as declarations to the TestingModule.
+// Providers and Services are added as providers to the TestingModule.
+// If we don't want something to be added to the TestingModule at all
+// we should mark it as a 'dependency'.
+const ngModule = MockBuilder(MyComponent, MyModule)
+ .keep(SomeModuleComponentDirectivePipeProvider1, {
+ dependency: true,
+ })
+ .mock(SomeModuleComponentDirectivePipeProvider1, {
+ dependency: true,
+ })
+ .replace(SomeModuleComponentDirectivePipeProvider1, anything1, {
+ dependency: true,
+ })
+ .build();
+// Imagine we want to render a structural directive by default.
+// Now we can do that via adding a 'render' flag in its config.
+const ngModule = MockBuilder(MyComponent, MyModule)
+ .mock(MyDirective, {
+ render: true,
+ })
+ .build();
+// Imagine the directive has own context and variables.
+// Then instead of flag we can set its context.
+const ngModule = MockBuilder(MyComponent, MyModule)
+ .mock(MyDirective, {
+ render: {
+ $implicit: something1,
+ variables: { something2: something3 },
+ },
+ })
+ .build();
+// If we use ContentChild in a component and we want to render it by default too
+// we should use its id for that in the same way as for a mocked directive.
+const ngModule = MockBuilder(MyComponent, MyModule)
+ .mock(MyDirective, {
+ render: {
+ blockId: true,
+ blockWithContext: {
+ $implicit: something1,
+ variables: { something2: something3 },
+ },
+ },
+ })
+ .build();
+```
+
+
+
+
+---
+
## MockRender
Provides a simple way to render anything for ease of testing directives, pipes, `@Inputs`, `@Outputs`, `@ContentChild` of a component, etc.
@@ -386,7 +611,8 @@ It is useful if you want to mock system tokens / services such as `APP_INITIALIZ
And don't forget to call `fixture.detectChanges()` and / or `await fixture.whenStable()` to trigger updates.
-### Usage Example
+(id: string): T;
};
};
+jasmine.getEnv().allowRespy(true);
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
diff --git a/e2e/angular9-ivy-true/karma.conf.js b/e2e/angular9-ivy-true/karma.conf.js
index 2e18deee6f..d9ba8c5766 100644
--- a/e2e/angular9-ivy-true/karma.conf.js
+++ b/e2e/angular9-ivy-true/karma.conf.js
@@ -28,7 +28,7 @@ module.exports = function (config) {
flags: ['--headless', '--disable-gpu', '--no-sandbox', '--disable-dev-shm-usage'],
},
},
- reporters: ['progress', 'kjhtml'],
+ reporters: ['kjhtml'],
port: 9876,
colors: true,
logLevel: config.LOG_INFO,
diff --git a/e2e/angular9-ivy-true/src/test.ts b/e2e/angular9-ivy-true/src/test.ts
index 99aa337871..ecf8a36b63 100644
--- a/e2e/angular9-ivy-true/src/test.ts
+++ b/e2e/angular9-ivy-true/src/test.ts
@@ -15,6 +15,7 @@ declare const require: {
(id: string): T;
};
};
+jasmine.getEnv().allowRespy(true);
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
diff --git a/examples-jasmine/MockBuilder/MockBuilder.spec.ts b/examples-jasmine/MockBuilder/MockBuilder.spec.ts
new file mode 100644
index 0000000000..6ddcc8ae47
--- /dev/null
+++ b/examples-jasmine/MockBuilder/MockBuilder.spec.ts
@@ -0,0 +1,223 @@
+import { HttpBackend, HttpClientModule } from '@angular/common/http';
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { inject, TestBed } from '@angular/core/testing';
+import { MockBuilder, MockRender } from 'ng-mocks';
+
+import {
+ ComponentContentChild,
+ ComponentWeDontWantToMock,
+ ComponentWeWantToMock,
+ MyComponent,
+ MyComponent1,
+ MyComponent2,
+ MyComponent3,
+} from './fixtures.components';
+import { DirectiveWeDontWantToMock, DirectiveWeWantToMock, MyDirective } from './fixtures.directives';
+import { ModuleWeDontWantToMock, ModuleWeWantToMockBesidesMyModule, MyModule } from './fixtures.modules';
+import {
+ MyPipe,
+ PipeWeDontWantToMock,
+ PipeWeWantToCustomize,
+ PipeWeWantToMock,
+ PipeWeWantToRestore,
+} from './fixtures.pipes';
+import {
+ AnythingWeWant1,
+ AnythingWeWant2,
+ MyCustomProvider1,
+ MyCustomProvider2,
+ MyCustomProvider3,
+ MyService1,
+ MyService2,
+ ServiceWeDontWantToMock,
+ ServiceWeWantToCustomize,
+ ServiceWeWantToMock,
+ TheSameAsAnyProvider,
+} from './fixtures.services';
+import {
+ INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK,
+ INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE,
+ INJECTION_TOKEN_WE_WANT_TO_MOCK,
+} from './fixtures.tokens';
+
+describe('MockBuilder:simple', () => {
+ beforeEach(async () => {
+ const ngModule = MockBuilder(MyComponent, MyModule)
+ // mocking configuration here
+ .build();
+
+ // now ngModule is
+ // {
+ // imports: [MockModule(MyModule)], // but MyComponent wasn't mocked for the testing purposes.
+ // }
+ // and we can simply pass it to the TestBed.
+ return TestBed.configureTestingModule(ngModule).compileComponents();
+ });
+
+ it('should render content ignoring all dependencies', () => {
+ const fixture = MockRender(MyComponent);
+ expect(fixture).toBeDefined();
+ expect(fixture.debugElement.nativeElement.innerHTML).toContain('My Content
');
+ });
+});
+
+describe('MockBuilder:deep', () => {
+ beforeEach(async () => {
+ const ngModule = MockBuilder(MyComponent, MyModule)
+ .mock(ComponentContentChild, {
+ render: {
+ block: {
+ $implicit: '-$implicit-',
+ variables: { a: { z: 'b' } },
+ },
+ },
+ })
+
+ .keep(ModuleWeDontWantToMock, {
+ dependency: true,
+ })
+ .keep(ComponentWeDontWantToMock, {
+ dependency: true,
+ })
+ .keep(DirectiveWeDontWantToMock, {
+ dependency: true,
+ })
+ .keep(PipeWeDontWantToMock, {
+ dependency: true,
+ })
+ .keep(ServiceWeDontWantToMock)
+ .keep(INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK)
+
+ // The same can be done with Components, Directives and Pipes.
+ // For Providers use .provider() or .mock().
+ .replace(HttpClientModule, HttpClientTestingModule, {
+ dependency: true,
+ })
+
+ .mock(ModuleWeWantToMockBesidesMyModule, {
+ dependency: true,
+ })
+ .mock(ComponentWeWantToMock, {
+ dependency: true,
+ })
+ .mock(DirectiveWeWantToMock, {
+ dependency: true,
+ render: {
+ $implicit: { a: '$' },
+ variables: { a: { b: 'b' } },
+ },
+ })
+ .mock(PipeWeWantToMock, {
+ dependency: true,
+ })
+ .mock(ServiceWeWantToMock) // makes all methods an empty function
+ .mock(INJECTION_TOKEN_WE_WANT_TO_MOCK) // makes its value undefined
+
+ .mock(PipeWeWantToCustomize, value => 'My Custom Result')
+ .mock(PipeWeWantToRestore, value => 'My Restored Pipe')
+ .mock(ServiceWeWantToCustomize, { prop1: true, getName: () => 'My Customized String' })
+ .mock(INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE, 'My_Token')
+
+ // All providers will be set into the TestModule.
+ .provide({
+ provide: AnythingWeWant1,
+ useValue: new TheSameAsAnyProvider(),
+ })
+ .provide({
+ provide: AnythingWeWant2,
+ useFactory: () => new TheSameAsAnyProvider(),
+ })
+ .provide(MyCustomProvider1)
+ .provide([MyCustomProvider2, MyCustomProvider3])
+
+ // Now the pipe won't be mocked.
+ .keep(PipeWeWantToRestore)
+
+ // Extra configuration.
+ .keep(MyDirective)
+ .keep(MyPipe)
+ .mock(MyService1)
+ .keep(MyService2)
+
+ // Even it belongs to the module that is marked as kept, the component will be mocked and replaced.
+ .mock(MyComponent3)
+
+ // and now we want to build our NgModule.
+ .build();
+ TestBed.configureTestingModule(ngModule);
+
+ // Extra configuration
+ TestBed.overrideTemplate(MyComponent1, 'If we need to tune testBed');
+ TestBed.overrideTemplate(MyComponent2, 'More callbacks');
+
+ return TestBed.compileComponents();
+ });
+
+ it('should render', inject([HttpBackend], (httpBackend: HttpBackend) => {
+ const fixture = MockRender(MyComponent);
+ expect(fixture).toBeDefined();
+ const content = fixture.debugElement.nativeElement.innerHTML.replace(//gm, '');
+ expect(content).toContain('My Content
');
+
+ expect(content).toContain('MyComponent1: If we need to tune testBed
');
+ expect(content).toContain('MyComponent2: More callbacks
');
+ expect(content).toContain('MyComponent3:
');
+ expect(content).toContain('ComponentWeDontWantToMock: ComponentWeDontWantToMock
');
+ expect(content).toContain('ComponentWeWantToMock:
');
+ expect(content).toContain('ComponentStructural: -$implicit- b
');
+
+ expect(content).toContain('MyDirective:
');
+ expect(content).toContain('DirectiveWeDontWantToMock:
');
+ expect(content).toContain('DirectiveWeWantToMock 1: render b');
+ expect(content).toContain('DirectiveWeWantToMock 2: render $');
+
+ expect(content).toContain('MyPipe: MyPipe:text
');
+ expect(content).toContain('PipeWeDontWantToMock: PipeWeDontWantToMock:text
');
+ expect(content).toContain('PipeWeWantToMock:
');
+ expect(content).toContain('PipeWeWantToCustomize: My Custom Result
');
+ expect(content).toContain('PipeWeWantToRestore: PipeWeWantToRestore:text
');
+
+ expect(content).toContain('INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK: INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK
');
+ expect(content).toContain('INJECTION_TOKEN_WE_WANT_TO_MOCK:
');
+ expect(content).toContain('INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE: My_Token
');
+
+ expect(content).toContain('anythingWeWant1: TheSameAsAnyProvider
');
+ expect(content).toContain('anythingWeWant2: TheSameAsAnyProvider
');
+ expect(content).toContain('myCustomProvider1: MyCustomProvider1
');
+ expect(content).toContain('myCustomProvider2: MyCustomProvider2
');
+ expect(content).toContain('myCustomProvider3: MyCustomProvider3
');
+
+ expect(content).toContain('myService1:
');
+ expect(content).toContain('myService2: MyService2
');
+ expect(content).toContain('serviceWeDontWantToMock: ServiceWeDontWantToMock
');
+ expect(content).toContain('serviceWeWantToCustomize: My Customized String
');
+ expect(content).toContain('serviceWeWantToMock:
');
+
+ // Checking that replacement works.
+ expect(httpBackend.constructor).toBeDefined();
+ expect(httpBackend.constructor.name).toEqual('HttpClientTestingBackend');
+ }));
+});
+
+describe('MockBuilder:promise', () => {
+ beforeEach(() =>
+ MockBuilder()
+ .keep(MyComponent1)
+ .keep(MyComponent2)
+
+ // In case if you need extra customization of TestBed in promise way.
+ .beforeCompileComponents(testBed => {
+ testBed.overrideTemplate(MyComponent1, 'If we need to tune testBed');
+ })
+ .beforeCompileComponents(testBed => {
+ testBed.overrideTemplate(MyComponent2, 'More callbacks');
+ })
+ );
+
+ it('should render content ignoring all dependencies', () => {
+ const fixture = MockRender('');
+ expect(fixture).toBeDefined();
+ expect(fixture.debugElement.nativeElement.innerHTML).toContain('If we need to tune testBed');
+ expect(fixture.debugElement.nativeElement.innerHTML).toContain('More callbacks');
+ });
+});
diff --git a/examples-jasmine/MockBuilder/fixtures.components.ts b/examples-jasmine/MockBuilder/fixtures.components.ts
new file mode 100644
index 0000000000..ac437e30d9
--- /dev/null
+++ b/examples-jasmine/MockBuilder/fixtures.components.ts
@@ -0,0 +1,159 @@
+import { Component, ContentChild, Inject, Input, Optional, TemplateRef } from '@angular/core';
+
+import { staticFalse } from '../../tests-jasmine';
+
+import {
+ AnythingWeWant1,
+ AnythingWeWant2,
+ MyCustomProvider1,
+ MyCustomProvider2,
+ MyCustomProvider3,
+ MyService1,
+ MyService2,
+ ServiceWeDontWantToMock,
+ ServiceWeWantToCustomize,
+ ServiceWeWantToMock,
+} from './fixtures.services';
+import {
+ INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK,
+ INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE,
+ INJECTION_TOKEN_WE_WANT_TO_MOCK,
+} from './fixtures.tokens';
+
+@Component({
+ selector: 'component-structural',
+ template: `
+
+
+
+ `,
+})
+export class ComponentContentChild {
+ @ContentChild('block', { ...staticFalse }) injectedBlock: TemplateRef;
+ @Input() items?: T[];
+}
+
+@Component({
+ selector: 'my-component',
+ template: `
+ My Content
+
+ MyComponent1:
+ MyComponent2:
+ MyComponent3:
+ ComponentWeDontWantToMock:
+ ComponentWeWantToMock:
+
+ MyDirective:
+ DirectiveWeDontWantToMock:
+
+ DirectiveWeWantToMock 1: render {{ z.b }}
+
+
+ DirectiveWeWantToMock 2: render {{ z.a }}
+
+
+ MyPipe: {{ 'text' | MyPipe }}
+ PipeWeDontWantToMock: {{ 'text' | PipeWeDontWantToMock }}
+ PipeWeWantToMock: {{ 'text' | PipeWeWantToMock }}
+ PipeWeWantToCustomize: {{ 'text' | PipeWeWantToCustomize }}
+ PipeWeWantToRestore: {{ 'text' | PipeWeWantToRestore }}
+
+ INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK: {{ t1v }}
+ INJECTION_TOKEN_WE_WANT_TO_MOCK: {{ t2v }}
+ INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE: {{ t3v }}
+
+ anythingWeWant1: {{ anythingWeWant1?.getName() }}
+ anythingWeWant2: {{ anythingWeWant2?.getName() }}
+ myCustomProvider1: {{ myCustomProvider1?.getName() }}
+ myCustomProvider2: {{ myCustomProvider2?.getName() }}
+ myCustomProvider3: {{ myCustomProvider3?.getName() }}
+
+ myService1: {{ myService1?.getName() }}
+ myService2: {{ myService2?.getName() }}
+ serviceWeDontWantToMock: {{ serviceWeDontWantToMock?.getName() }}
+ serviceWeWantToCustomize: {{ serviceWeWantToCustomize?.getName() }}
+ serviceWeWantToMock: {{ serviceWeWantToMock?.getName() }}
+
+
+
+ ComponentStructural: {{ value }} {{ b.z }}
+
+
+ `,
+})
+export class MyComponent {
+ public readonly anythingWeWant1: AnythingWeWant1;
+ public readonly anythingWeWant2: AnythingWeWant2;
+ public readonly myCustomProvider1: MyCustomProvider1;
+ public readonly myCustomProvider2: MyCustomProvider2;
+ public readonly myCustomProvider3: MyCustomProvider3;
+ public readonly myService1: MyService1;
+ public readonly myService2: MyService2;
+ public readonly serviceWeDontWantToMock: ServiceWeDontWantToMock;
+ public readonly serviceWeWantToCustomize: ServiceWeWantToCustomize;
+ public readonly serviceWeWantToMock: ServiceWeWantToMock;
+ public readonly t1v: string;
+ public readonly t2v: string;
+ public readonly t3v: string;
+
+ constructor(
+ @Optional() @Inject(INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK) t1: string,
+ @Optional() @Inject(INJECTION_TOKEN_WE_WANT_TO_MOCK) t2: string,
+ @Optional() @Inject(INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE) t3: string,
+ @Optional() anythingWeWant1: AnythingWeWant1,
+ @Optional() anythingWeWant2: AnythingWeWant2,
+ @Optional() myCustomProvider1: MyCustomProvider1,
+ @Optional() myCustomProvider2: MyCustomProvider2,
+ @Optional() myCustomProvider3: MyCustomProvider3,
+ @Optional() myService1: MyService1,
+ @Optional() myService2: MyService2,
+ @Optional() serviceWeDontWantToMock: ServiceWeDontWantToMock,
+ @Optional() serviceWeWantToMock: ServiceWeWantToMock,
+ @Optional() serviceWeWantToCustomize: ServiceWeWantToCustomize
+ ) {
+ this.t1v = t1;
+ this.t2v = t2;
+ this.t3v = t3;
+ this.anythingWeWant1 = anythingWeWant1;
+ this.anythingWeWant2 = anythingWeWant2;
+ this.myCustomProvider1 = myCustomProvider1;
+ this.myCustomProvider2 = myCustomProvider2;
+ this.myCustomProvider3 = myCustomProvider3;
+ this.myService1 = myService1;
+ this.myService2 = myService2;
+ this.serviceWeDontWantToMock = serviceWeDontWantToMock;
+ this.serviceWeWantToCustomize = serviceWeWantToCustomize;
+ this.serviceWeWantToMock = serviceWeWantToMock;
+ }
+}
+
+@Component({
+ selector: 'component-1',
+ template: 'MyComponent1',
+})
+export class MyComponent1 {}
+
+@Component({
+ selector: 'component-2',
+ template: 'MyComponent2',
+})
+export class MyComponent2 {}
+
+@Component({
+ selector: 'component-3',
+ template: 'MyComponent3',
+})
+export class MyComponent3 {}
+
+@Component({
+ selector: 'dont-want',
+ template: 'ComponentWeDontWantToMock',
+})
+export class ComponentWeDontWantToMock {}
+
+@Component({
+ selector: 'do-want',
+ template: 'ComponentWeWantToMock',
+})
+export class ComponentWeWantToMock {}
diff --git a/examples-jasmine/MockBuilder/fixtures.directives.ts b/examples-jasmine/MockBuilder/fixtures.directives.ts
new file mode 100644
index 0000000000..6dbb2e86f8
--- /dev/null
+++ b/examples-jasmine/MockBuilder/fixtures.directives.ts
@@ -0,0 +1,16 @@
+import { Directive } from '@angular/core';
+
+@Directive({
+ selector: 'MyDirective',
+})
+export class MyDirective {}
+
+@Directive({
+ selector: 'WeDontWantToMock',
+})
+export class DirectiveWeDontWantToMock {}
+
+@Directive({
+ selector: '[WeWantToMock]',
+})
+export class DirectiveWeWantToMock {}
diff --git a/examples-jasmine/MockBuilder/fixtures.modules.ts b/examples-jasmine/MockBuilder/fixtures.modules.ts
new file mode 100644
index 0000000000..264824c22b
--- /dev/null
+++ b/examples-jasmine/MockBuilder/fixtures.modules.ts
@@ -0,0 +1,88 @@
+import { HttpClientModule } from '@angular/common/http';
+import { NgModule } from '@angular/core';
+
+import {
+ ComponentContentChild,
+ ComponentWeDontWantToMock,
+ ComponentWeWantToMock,
+ MyComponent,
+ MyComponent1,
+ MyComponent2,
+ MyComponent3,
+} from './fixtures.components';
+import { DirectiveWeDontWantToMock, DirectiveWeWantToMock, MyDirective } from './fixtures.directives';
+import {
+ MyPipe,
+ PipeWeDontWantToMock,
+ PipeWeWantToCustomize,
+ PipeWeWantToMock,
+ PipeWeWantToRestore,
+} from './fixtures.pipes';
+import {
+ MyService1,
+ MyService2,
+ ServiceWeDontWantToMock,
+ ServiceWeWantToCustomize,
+ ServiceWeWantToMock,
+} from './fixtures.services';
+import {
+ INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK,
+ INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE,
+ INJECTION_TOKEN_WE_WANT_TO_MOCK,
+} from './fixtures.tokens';
+import { CommonModule } from '@angular/common';
+
+@NgModule({
+ declarations: [
+ ComponentWeDontWantToMock,
+ ComponentWeWantToMock,
+ DirectiveWeDontWantToMock,
+ DirectiveWeWantToMock,
+ PipeWeDontWantToMock,
+ PipeWeWantToMock,
+ PipeWeWantToCustomize,
+ PipeWeWantToRestore,
+ ],
+ exports: [
+ ComponentWeDontWantToMock,
+ ComponentWeWantToMock,
+ DirectiveWeDontWantToMock,
+ DirectiveWeWantToMock,
+ PipeWeDontWantToMock,
+ PipeWeWantToMock,
+ PipeWeWantToCustomize,
+ PipeWeWantToRestore,
+ ],
+ providers: [
+ ServiceWeDontWantToMock,
+ ServiceWeWantToMock,
+ {
+ provide: INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK,
+ useValue: 'INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK',
+ },
+ {
+ provide: INJECTION_TOKEN_WE_WANT_TO_MOCK,
+ useValue: 'INJECTION_TOKEN_WE_WANT_TO_MOCK',
+ },
+ {
+ provide: INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE,
+ useValue: 'INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE',
+ },
+ ],
+})
+export class ModuleWeWantToMockBesidesMyModule {}
+
+@NgModule({
+ declarations: [MyComponent1, MyComponent2, MyComponent3, ComponentContentChild],
+ exports: [MyComponent1, MyComponent2, MyComponent3, ComponentContentChild],
+ imports: [CommonModule],
+})
+export class ModuleWeDontWantToMock {}
+
+@NgModule({
+ declarations: [MyComponent, MyDirective, MyPipe],
+ exports: [MyComponent, MyDirective, MyPipe],
+ imports: [HttpClientModule, ModuleWeWantToMockBesidesMyModule, ModuleWeDontWantToMock],
+ providers: [MyService1, MyService2, ServiceWeWantToCustomize],
+})
+export class MyModule {}
diff --git a/examples-jasmine/MockBuilder/fixtures.pipes.ts b/examples-jasmine/MockBuilder/fixtures.pipes.ts
new file mode 100644
index 0000000000..a1034148cb
--- /dev/null
+++ b/examples-jasmine/MockBuilder/fixtures.pipes.ts
@@ -0,0 +1,56 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'MyPipe',
+})
+export class MyPipe implements PipeTransform {
+ protected prefix = 'MyPipe:';
+
+ public transform(value: any, ...args: any[]): any {
+ return this.prefix + value;
+ }
+}
+
+@Pipe({
+ name: 'PipeWeDontWantToMock',
+})
+export class PipeWeDontWantToMock implements PipeTransform {
+ protected prefix = 'PipeWeDontWantToMock:';
+
+ public transform(value: any, ...args: any[]): any {
+ return this.prefix + value;
+ }
+}
+
+@Pipe({
+ name: 'PipeWeWantToMock',
+})
+export class PipeWeWantToMock implements PipeTransform {
+ protected prefix = 'PipeWeWantToMock:';
+
+ public transform(value: any, ...args: any[]): any {
+ return this.prefix + value;
+ }
+}
+
+@Pipe({
+ name: 'PipeWeWantToCustomize',
+})
+export class PipeWeWantToCustomize implements PipeTransform {
+ protected prefix = 'PipeWeWantToCustomize:';
+
+ public transform(value: any, ...args: any[]): any {
+ return this.prefix + value;
+ }
+}
+
+@Pipe({
+ name: 'PipeWeWantToRestore',
+})
+export class PipeWeWantToRestore implements PipeTransform {
+ protected prefix = 'PipeWeWantToRestore:';
+
+ public transform(value: any, ...args: any[]): any {
+ return this.prefix + value;
+ }
+}
diff --git a/examples-jasmine/MockBuilder/fixtures.services.ts b/examples-jasmine/MockBuilder/fixtures.services.ts
new file mode 100644
index 0000000000..4fb36c910a
--- /dev/null
+++ b/examples-jasmine/MockBuilder/fixtures.services.ts
@@ -0,0 +1,100 @@
+import { Injectable } from '@angular/core';
+
+@Injectable()
+export class MyService1 {
+ protected value = 'MyService1';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class MyService2 {
+ protected value = 'MyService2';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class ServiceWeDontWantToMock {
+ protected value = 'ServiceWeDontWantToMock';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class ServiceWeWantToMock {
+ protected value = 'ServiceWeWantToMock';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class ServiceWeWantToCustomize {
+ protected value = 'ServiceWeWantToCustomize';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class AnythingWeWant1 {
+ protected value = 'AnythingWeWant1';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class TheSameAsAnyProvider {
+ protected value = 'TheSameAsAnyProvider';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class AnythingWeWant2 {
+ protected value = 'AnythingWeWant2';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class MyCustomProvider1 {
+ protected value = 'MyCustomProvider1';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class MyCustomProvider2 {
+ protected value = 'MyCustomProvider2';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class MyCustomProvider3 {
+ protected value = 'MyCustomProvider3';
+
+ public getName() {
+ return this.value;
+ }
+}
diff --git a/examples-jasmine/MockBuilder/fixtures.tokens.ts b/examples-jasmine/MockBuilder/fixtures.tokens.ts
new file mode 100644
index 0000000000..8d527302f7
--- /dev/null
+++ b/examples-jasmine/MockBuilder/fixtures.tokens.ts
@@ -0,0 +1,7 @@
+import { InjectionToken } from '@angular/core';
+
+export const INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK = new InjectionToken('INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK');
+
+export const INJECTION_TOKEN_WE_WANT_TO_MOCK = new InjectionToken('INJECTION_TOKEN_WE_WANT_TO_MOCK');
+
+export const INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE = new InjectionToken('INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE');
diff --git a/examples-jasmine/MockDirective-Structural/MockDirective.spec.ts b/examples-jasmine/MockDirective-Structural/MockDirective.spec.ts
index d24960be6f..c3dcaa886a 100644
--- a/examples-jasmine/MockDirective-Structural/MockDirective.spec.ts
+++ b/examples-jasmine/MockDirective-Structural/MockDirective.spec.ts
@@ -30,11 +30,11 @@ describe('MockDirective', () => {
>;
// now we assert that nothing has been rendered inside of the structural directive by default.
- expect(fixture.debugElement.nativeElement.innerText).not.toContain('content');
+ expect(fixture.debugElement.nativeElement.innerHTML).not.toContain('>content<');
// and now we render it manually.
mockedDirectiveInstance.__render();
- expect(fixture.debugElement.nativeElement.innerText).toContain('content');
+ expect(fixture.debugElement.nativeElement.innerHTML).toContain('>content<');
// let's pretend Dependency Directive (unmocked) has 'someInput' as an input
// the input value will be passed into the mocked directive so you can assert on it
diff --git a/examples-jasmine/MockReactiveForms/MockReactiveForms.spec.ts b/examples-jasmine/MockReactiveForms/MockReactiveForms.spec.ts
index e2e97f67a0..93f1440b57 100644
--- a/examples-jasmine/MockReactiveForms/MockReactiveForms.spec.ts
+++ b/examples-jasmine/MockReactiveForms/MockReactiveForms.spec.ts
@@ -31,6 +31,6 @@ describe('MockReactiveForms', () => {
spyOn(mockedReactiveFormComponent, 'writeValue');
component.formControl.setValue('bar');
- expect(mockedReactiveFormComponent.writeValue as any).toHaveBeenCalledWith('bar');
+ expect(mockedReactiveFormComponent.writeValue).toHaveBeenCalledWith('bar');
});
});
diff --git a/examples-jasmine/NG_MOCKS/NG_MOCKS.spec.ts b/examples-jasmine/NG_MOCKS/NG_MOCKS.spec.ts
new file mode 100644
index 0000000000..6c3a7cdf06
--- /dev/null
+++ b/examples-jasmine/NG_MOCKS/NG_MOCKS.spec.ts
@@ -0,0 +1,122 @@
+import { HttpClientModule } from '@angular/common/http';
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { inject, TestBed } from '@angular/core/testing';
+import { isMockedNgDefOf, MockBuilder, NG_MOCKS } from 'ng-mocks';
+
+import {
+ ComponentWeDontWantToMock,
+ ComponentWeWantToMock,
+ MyComponent,
+ MyComponent1,
+ MyComponent2,
+ MyComponent3,
+} from './fixtures.components';
+import { DirectiveWeDontWantToMock, DirectiveWeWantToMock } from './fixtures.directives';
+import { ModuleWeDontWantToMock, ModuleWeWantToMockBesidesMyModule, MyModule } from './fixtures.modules';
+import { PipeWeDontWantToMock, PipeWeWantToMock, PipeWeWantToRestore } from './fixtures.pipes';
+import { ServiceWeDontWantToMock, ServiceWeWantToCustomize, ServiceWeWantToMock } from './fixtures.services';
+import {
+ INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK,
+ INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE,
+ INJECTION_TOKEN_WE_WANT_TO_MOCK,
+} from './fixtures.tokens';
+
+describe('NG_MOCKS:deep', () => {
+ beforeEach(async () => {
+ const ngModule = MockBuilder(MyComponent, MyModule)
+ .keep(ModuleWeDontWantToMock)
+ .keep(ComponentWeDontWantToMock)
+ .keep(DirectiveWeDontWantToMock)
+ .keep(PipeWeDontWantToMock)
+ .keep(ServiceWeDontWantToMock)
+ .keep(INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK)
+
+ .replace(HttpClientModule, HttpClientTestingModule)
+
+ .mock(ModuleWeWantToMockBesidesMyModule)
+ .mock(ComponentWeWantToMock)
+ .mock(DirectiveWeWantToMock)
+ .mock(PipeWeWantToMock)
+ .mock(ServiceWeWantToMock) // makes all methods an empty function
+ .mock(INJECTION_TOKEN_WE_WANT_TO_MOCK) // makes its value undefined
+
+ .mock(ServiceWeWantToCustomize, { prop1: true, getName: () => 'My Customized String' })
+ .mock(INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE, 'My_Token')
+
+ // Now the pipe won't be mocked.
+ .keep(PipeWeWantToRestore)
+
+ // Even it belongs to the module to keep it still will be mocked and replaced.
+ .mock(MyComponent3)
+
+ // and now we want to build our NgModule.
+ .build();
+ TestBed.configureTestingModule(ngModule);
+
+ // Extra configuration
+ TestBed.overrideTemplate(MyComponent1, 'If we need to tune testBed');
+ TestBed.overrideTemplate(MyComponent2, 'More callbacks');
+
+ return TestBed.compileComponents();
+ });
+
+ it('should contain mocks', inject([NG_MOCKS], (mocks: Map) => {
+ // main part
+ const myComponent = mocks.get(MyComponent);
+ expect(myComponent).toBe(MyComponent);
+ const myModule = mocks.get(MyModule);
+ expect(isMockedNgDefOf(myModule, MyModule, 'm')).toBeTruthy();
+
+ // keep
+ const componentWeDontWantToMock = mocks.get(ComponentWeDontWantToMock);
+ expect(componentWeDontWantToMock).toBe(ComponentWeDontWantToMock);
+ const directiveWeDontWantToMock = mocks.get(DirectiveWeDontWantToMock);
+ expect(directiveWeDontWantToMock).toBe(DirectiveWeDontWantToMock);
+ const pipeWeDontWantToMock = mocks.get(PipeWeDontWantToMock);
+ expect(pipeWeDontWantToMock).toBe(PipeWeDontWantToMock);
+ const serviceWeDontWantToMock = mocks.get(ServiceWeDontWantToMock);
+ expect(serviceWeDontWantToMock).toBe(ServiceWeDontWantToMock);
+ const injectionTokenWeDontWantToMock = mocks.get(INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK);
+ expect(injectionTokenWeDontWantToMock).toBe(INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK);
+
+ // replace
+ const httpClientModule = mocks.get(HttpClientModule);
+ expect(httpClientModule).toBe(HttpClientTestingModule);
+
+ // mock
+ const moduleWeWantToMockBesidesMyModule = mocks.get(ModuleWeWantToMockBesidesMyModule);
+ expect(isMockedNgDefOf(moduleWeWantToMockBesidesMyModule, ModuleWeWantToMockBesidesMyModule, 'm')).toBeTruthy();
+ const componentWeWantToMock = mocks.get(ComponentWeWantToMock);
+ expect(isMockedNgDefOf(componentWeWantToMock, ComponentWeWantToMock, 'c')).toBeTruthy();
+ const directiveWeWantToMock = mocks.get(DirectiveWeWantToMock);
+ expect(isMockedNgDefOf(directiveWeWantToMock, DirectiveWeWantToMock, 'd')).toBeTruthy();
+ const pipeWeWantToMock = mocks.get(PipeWeWantToMock);
+ expect(isMockedNgDefOf(pipeWeWantToMock, PipeWeWantToMock, 'p')).toBeTruthy();
+ const serviceWeWantToMock = mocks.get(ServiceWeWantToMock);
+ expect(serviceWeWantToMock).toBeDefined();
+ expect(serviceWeWantToMock.useValue).toBeDefined();
+ expect(serviceWeWantToMock.useValue.getName).toBeDefined();
+ expect(serviceWeWantToMock.useValue.getName()).toBeUndefined();
+ expect(mocks.has(INJECTION_TOKEN_WE_WANT_TO_MOCK)).toBeDefined();
+ expect(mocks.get(INJECTION_TOKEN_WE_WANT_TO_MOCK)).toBeUndefined();
+
+ // customize
+ const serviceWeWantToCustomize = mocks.get(ServiceWeWantToCustomize);
+ expect(serviceWeWantToCustomize).toBeDefined();
+ expect(serviceWeWantToCustomize.useValue).toBeDefined();
+ expect(serviceWeWantToCustomize.useValue.getName).toBeDefined();
+ expect(serviceWeWantToCustomize.useValue.getName()).toEqual('My Customized String');
+ expect(serviceWeWantToCustomize.useValue.prop1).toEqual(true);
+ const injectionTokenWeWantToCustomize = mocks.get(INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE);
+ expect(injectionTokenWeWantToCustomize).toBeDefined();
+ expect(injectionTokenWeWantToCustomize.useValue).toEqual('My_Token');
+
+ // restore
+ const pipeWeWantToRestore = mocks.get(PipeWeWantToRestore);
+ expect(pipeWeWantToRestore).toBe(PipeWeWantToRestore);
+
+ // mock nested
+ const myComponent3 = mocks.get(MyComponent3);
+ expect(isMockedNgDefOf(myComponent3, MyComponent3, 'c')).toBeTruthy();
+ }));
+});
diff --git a/examples-jasmine/NG_MOCKS/fixtures.components.ts b/examples-jasmine/NG_MOCKS/fixtures.components.ts
new file mode 100644
index 0000000000..f0c247c9f3
--- /dev/null
+++ b/examples-jasmine/NG_MOCKS/fixtures.components.ts
@@ -0,0 +1,110 @@
+import { Component, ContentChild, Inject, Input, Optional, TemplateRef } from '@angular/core';
+
+import { staticFalse } from '../../tests-jasmine';
+
+import {
+ AnythingWeWant1,
+ AnythingWeWant2,
+ MyCustomProvider1,
+ MyCustomProvider2,
+ MyCustomProvider3,
+ MyService1,
+ MyService2,
+ ServiceWeDontWantToMock,
+ ServiceWeWantToCustomize,
+ ServiceWeWantToMock,
+} from './fixtures.services';
+import {
+ INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK,
+ INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE,
+ INJECTION_TOKEN_WE_WANT_TO_MOCK,
+} from './fixtures.tokens';
+
+@Component({
+ selector: 'component-structural',
+ template: '',
+})
+export class ComponentContentChild {
+ @ContentChild('block', { ...staticFalse }) injectedBlock: TemplateRef;
+ @Input() items?: T[];
+}
+
+@Component({
+ selector: 'my-component',
+ template: '',
+})
+export class MyComponent {
+ public readonly anythingWeWant1: AnythingWeWant1;
+ public readonly anythingWeWant2: AnythingWeWant2;
+ public readonly myCustomProvider1: MyCustomProvider1;
+ public readonly myCustomProvider2: MyCustomProvider2;
+ public readonly myCustomProvider3: MyCustomProvider3;
+ public readonly myService1: MyService1;
+ public readonly myService2: MyService2;
+ public readonly serviceWeDontWantToMock: ServiceWeDontWantToMock;
+ public readonly serviceWeWantToCustomize: ServiceWeWantToCustomize;
+ public readonly serviceWeWantToMock: ServiceWeWantToMock;
+ public readonly t1v: string;
+ public readonly t2v: string;
+ public readonly t3v: string;
+
+ constructor(
+ @Optional() @Inject(INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK) t1: string,
+ @Optional() @Inject(INJECTION_TOKEN_WE_WANT_TO_MOCK) t2: string,
+ @Optional() @Inject(INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE) t3: string,
+ @Optional() anythingWeWant1: AnythingWeWant1,
+ @Optional() anythingWeWant2: AnythingWeWant2,
+ @Optional() myCustomProvider1: MyCustomProvider1,
+ @Optional() myCustomProvider2: MyCustomProvider2,
+ @Optional() myCustomProvider3: MyCustomProvider3,
+ @Optional() myService1: MyService1,
+ @Optional() myService2: MyService2,
+ @Optional() serviceWeDontWantToMock: ServiceWeDontWantToMock,
+ @Optional() serviceWeWantToMock: ServiceWeWantToMock,
+ @Optional() serviceWeWantToCustomize: ServiceWeWantToCustomize
+ ) {
+ this.t1v = t1;
+ this.t2v = t2;
+ this.t3v = t3;
+ this.anythingWeWant1 = anythingWeWant1;
+ this.anythingWeWant2 = anythingWeWant2;
+ this.myCustomProvider1 = myCustomProvider1;
+ this.myCustomProvider2 = myCustomProvider2;
+ this.myCustomProvider3 = myCustomProvider3;
+ this.myService1 = myService1;
+ this.myService2 = myService2;
+ this.serviceWeDontWantToMock = serviceWeDontWantToMock;
+ this.serviceWeWantToCustomize = serviceWeWantToCustomize;
+ this.serviceWeWantToMock = serviceWeWantToMock;
+ }
+}
+
+@Component({
+ selector: 'component-1',
+ template: 'MyComponent1',
+})
+export class MyComponent1 {}
+
+@Component({
+ selector: 'component-2',
+ template: 'MyComponent2',
+})
+export class MyComponent2 {}
+
+@Component({
+ selector: 'component-3',
+ template: 'MyComponent3',
+})
+export class MyComponent3 {}
+
+@Component({
+ selector: 'dont-want',
+ template: 'ComponentWeDontWantToMock',
+})
+export class ComponentWeDontWantToMock {}
+
+@Component({
+ selector: 'do-want',
+ template: 'ComponentWeWantToMock',
+})
+export class ComponentWeWantToMock {}
diff --git a/examples-jasmine/NG_MOCKS/fixtures.directives.ts b/examples-jasmine/NG_MOCKS/fixtures.directives.ts
new file mode 100644
index 0000000000..6dbb2e86f8
--- /dev/null
+++ b/examples-jasmine/NG_MOCKS/fixtures.directives.ts
@@ -0,0 +1,16 @@
+import { Directive } from '@angular/core';
+
+@Directive({
+ selector: 'MyDirective',
+})
+export class MyDirective {}
+
+@Directive({
+ selector: 'WeDontWantToMock',
+})
+export class DirectiveWeDontWantToMock {}
+
+@Directive({
+ selector: '[WeWantToMock]',
+})
+export class DirectiveWeWantToMock {}
diff --git a/examples-jasmine/NG_MOCKS/fixtures.modules.ts b/examples-jasmine/NG_MOCKS/fixtures.modules.ts
new file mode 100644
index 0000000000..264824c22b
--- /dev/null
+++ b/examples-jasmine/NG_MOCKS/fixtures.modules.ts
@@ -0,0 +1,88 @@
+import { HttpClientModule } from '@angular/common/http';
+import { NgModule } from '@angular/core';
+
+import {
+ ComponentContentChild,
+ ComponentWeDontWantToMock,
+ ComponentWeWantToMock,
+ MyComponent,
+ MyComponent1,
+ MyComponent2,
+ MyComponent3,
+} from './fixtures.components';
+import { DirectiveWeDontWantToMock, DirectiveWeWantToMock, MyDirective } from './fixtures.directives';
+import {
+ MyPipe,
+ PipeWeDontWantToMock,
+ PipeWeWantToCustomize,
+ PipeWeWantToMock,
+ PipeWeWantToRestore,
+} from './fixtures.pipes';
+import {
+ MyService1,
+ MyService2,
+ ServiceWeDontWantToMock,
+ ServiceWeWantToCustomize,
+ ServiceWeWantToMock,
+} from './fixtures.services';
+import {
+ INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK,
+ INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE,
+ INJECTION_TOKEN_WE_WANT_TO_MOCK,
+} from './fixtures.tokens';
+import { CommonModule } from '@angular/common';
+
+@NgModule({
+ declarations: [
+ ComponentWeDontWantToMock,
+ ComponentWeWantToMock,
+ DirectiveWeDontWantToMock,
+ DirectiveWeWantToMock,
+ PipeWeDontWantToMock,
+ PipeWeWantToMock,
+ PipeWeWantToCustomize,
+ PipeWeWantToRestore,
+ ],
+ exports: [
+ ComponentWeDontWantToMock,
+ ComponentWeWantToMock,
+ DirectiveWeDontWantToMock,
+ DirectiveWeWantToMock,
+ PipeWeDontWantToMock,
+ PipeWeWantToMock,
+ PipeWeWantToCustomize,
+ PipeWeWantToRestore,
+ ],
+ providers: [
+ ServiceWeDontWantToMock,
+ ServiceWeWantToMock,
+ {
+ provide: INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK,
+ useValue: 'INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK',
+ },
+ {
+ provide: INJECTION_TOKEN_WE_WANT_TO_MOCK,
+ useValue: 'INJECTION_TOKEN_WE_WANT_TO_MOCK',
+ },
+ {
+ provide: INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE,
+ useValue: 'INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE',
+ },
+ ],
+})
+export class ModuleWeWantToMockBesidesMyModule {}
+
+@NgModule({
+ declarations: [MyComponent1, MyComponent2, MyComponent3, ComponentContentChild],
+ exports: [MyComponent1, MyComponent2, MyComponent3, ComponentContentChild],
+ imports: [CommonModule],
+})
+export class ModuleWeDontWantToMock {}
+
+@NgModule({
+ declarations: [MyComponent, MyDirective, MyPipe],
+ exports: [MyComponent, MyDirective, MyPipe],
+ imports: [HttpClientModule, ModuleWeWantToMockBesidesMyModule, ModuleWeDontWantToMock],
+ providers: [MyService1, MyService2, ServiceWeWantToCustomize],
+})
+export class MyModule {}
diff --git a/examples-jasmine/NG_MOCKS/fixtures.pipes.ts b/examples-jasmine/NG_MOCKS/fixtures.pipes.ts
new file mode 100644
index 0000000000..a1034148cb
--- /dev/null
+++ b/examples-jasmine/NG_MOCKS/fixtures.pipes.ts
@@ -0,0 +1,56 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'MyPipe',
+})
+export class MyPipe implements PipeTransform {
+ protected prefix = 'MyPipe:';
+
+ public transform(value: any, ...args: any[]): any {
+ return this.prefix + value;
+ }
+}
+
+@Pipe({
+ name: 'PipeWeDontWantToMock',
+})
+export class PipeWeDontWantToMock implements PipeTransform {
+ protected prefix = 'PipeWeDontWantToMock:';
+
+ public transform(value: any, ...args: any[]): any {
+ return this.prefix + value;
+ }
+}
+
+@Pipe({
+ name: 'PipeWeWantToMock',
+})
+export class PipeWeWantToMock implements PipeTransform {
+ protected prefix = 'PipeWeWantToMock:';
+
+ public transform(value: any, ...args: any[]): any {
+ return this.prefix + value;
+ }
+}
+
+@Pipe({
+ name: 'PipeWeWantToCustomize',
+})
+export class PipeWeWantToCustomize implements PipeTransform {
+ protected prefix = 'PipeWeWantToCustomize:';
+
+ public transform(value: any, ...args: any[]): any {
+ return this.prefix + value;
+ }
+}
+
+@Pipe({
+ name: 'PipeWeWantToRestore',
+})
+export class PipeWeWantToRestore implements PipeTransform {
+ protected prefix = 'PipeWeWantToRestore:';
+
+ public transform(value: any, ...args: any[]): any {
+ return this.prefix + value;
+ }
+}
diff --git a/examples-jasmine/NG_MOCKS/fixtures.services.ts b/examples-jasmine/NG_MOCKS/fixtures.services.ts
new file mode 100644
index 0000000000..4fb36c910a
--- /dev/null
+++ b/examples-jasmine/NG_MOCKS/fixtures.services.ts
@@ -0,0 +1,100 @@
+import { Injectable } from '@angular/core';
+
+@Injectable()
+export class MyService1 {
+ protected value = 'MyService1';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class MyService2 {
+ protected value = 'MyService2';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class ServiceWeDontWantToMock {
+ protected value = 'ServiceWeDontWantToMock';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class ServiceWeWantToMock {
+ protected value = 'ServiceWeWantToMock';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class ServiceWeWantToCustomize {
+ protected value = 'ServiceWeWantToCustomize';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class AnythingWeWant1 {
+ protected value = 'AnythingWeWant1';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class TheSameAsAnyProvider {
+ protected value = 'TheSameAsAnyProvider';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class AnythingWeWant2 {
+ protected value = 'AnythingWeWant2';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class MyCustomProvider1 {
+ protected value = 'MyCustomProvider1';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class MyCustomProvider2 {
+ protected value = 'MyCustomProvider2';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class MyCustomProvider3 {
+ protected value = 'MyCustomProvider3';
+
+ public getName() {
+ return this.value;
+ }
+}
diff --git a/examples-jasmine/NG_MOCKS/fixtures.tokens.ts b/examples-jasmine/NG_MOCKS/fixtures.tokens.ts
new file mode 100644
index 0000000000..8d527302f7
--- /dev/null
+++ b/examples-jasmine/NG_MOCKS/fixtures.tokens.ts
@@ -0,0 +1,7 @@
+import { InjectionToken } from '@angular/core';
+
+export const INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK = new InjectionToken('INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK');
+
+export const INJECTION_TOKEN_WE_WANT_TO_MOCK = new InjectionToken('INJECTION_TOKEN_WE_WANT_TO_MOCK');
+
+export const INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE = new InjectionToken('INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE');
diff --git a/examples-jest/MockBuilder/MockBuilder.spec.ts b/examples-jest/MockBuilder/MockBuilder.spec.ts
new file mode 100644
index 0000000000..6ddcc8ae47
--- /dev/null
+++ b/examples-jest/MockBuilder/MockBuilder.spec.ts
@@ -0,0 +1,223 @@
+import { HttpBackend, HttpClientModule } from '@angular/common/http';
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { inject, TestBed } from '@angular/core/testing';
+import { MockBuilder, MockRender } from 'ng-mocks';
+
+import {
+ ComponentContentChild,
+ ComponentWeDontWantToMock,
+ ComponentWeWantToMock,
+ MyComponent,
+ MyComponent1,
+ MyComponent2,
+ MyComponent3,
+} from './fixtures.components';
+import { DirectiveWeDontWantToMock, DirectiveWeWantToMock, MyDirective } from './fixtures.directives';
+import { ModuleWeDontWantToMock, ModuleWeWantToMockBesidesMyModule, MyModule } from './fixtures.modules';
+import {
+ MyPipe,
+ PipeWeDontWantToMock,
+ PipeWeWantToCustomize,
+ PipeWeWantToMock,
+ PipeWeWantToRestore,
+} from './fixtures.pipes';
+import {
+ AnythingWeWant1,
+ AnythingWeWant2,
+ MyCustomProvider1,
+ MyCustomProvider2,
+ MyCustomProvider3,
+ MyService1,
+ MyService2,
+ ServiceWeDontWantToMock,
+ ServiceWeWantToCustomize,
+ ServiceWeWantToMock,
+ TheSameAsAnyProvider,
+} from './fixtures.services';
+import {
+ INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK,
+ INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE,
+ INJECTION_TOKEN_WE_WANT_TO_MOCK,
+} from './fixtures.tokens';
+
+describe('MockBuilder:simple', () => {
+ beforeEach(async () => {
+ const ngModule = MockBuilder(MyComponent, MyModule)
+ // mocking configuration here
+ .build();
+
+ // now ngModule is
+ // {
+ // imports: [MockModule(MyModule)], // but MyComponent wasn't mocked for the testing purposes.
+ // }
+ // and we can simply pass it to the TestBed.
+ return TestBed.configureTestingModule(ngModule).compileComponents();
+ });
+
+ it('should render content ignoring all dependencies', () => {
+ const fixture = MockRender(MyComponent);
+ expect(fixture).toBeDefined();
+ expect(fixture.debugElement.nativeElement.innerHTML).toContain('My Content
');
+ });
+});
+
+describe('MockBuilder:deep', () => {
+ beforeEach(async () => {
+ const ngModule = MockBuilder(MyComponent, MyModule)
+ .mock(ComponentContentChild, {
+ render: {
+ block: {
+ $implicit: '-$implicit-',
+ variables: { a: { z: 'b' } },
+ },
+ },
+ })
+
+ .keep(ModuleWeDontWantToMock, {
+ dependency: true,
+ })
+ .keep(ComponentWeDontWantToMock, {
+ dependency: true,
+ })
+ .keep(DirectiveWeDontWantToMock, {
+ dependency: true,
+ })
+ .keep(PipeWeDontWantToMock, {
+ dependency: true,
+ })
+ .keep(ServiceWeDontWantToMock)
+ .keep(INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK)
+
+ // The same can be done with Components, Directives and Pipes.
+ // For Providers use .provider() or .mock().
+ .replace(HttpClientModule, HttpClientTestingModule, {
+ dependency: true,
+ })
+
+ .mock(ModuleWeWantToMockBesidesMyModule, {
+ dependency: true,
+ })
+ .mock(ComponentWeWantToMock, {
+ dependency: true,
+ })
+ .mock(DirectiveWeWantToMock, {
+ dependency: true,
+ render: {
+ $implicit: { a: '$' },
+ variables: { a: { b: 'b' } },
+ },
+ })
+ .mock(PipeWeWantToMock, {
+ dependency: true,
+ })
+ .mock(ServiceWeWantToMock) // makes all methods an empty function
+ .mock(INJECTION_TOKEN_WE_WANT_TO_MOCK) // makes its value undefined
+
+ .mock(PipeWeWantToCustomize, value => 'My Custom Result')
+ .mock(PipeWeWantToRestore, value => 'My Restored Pipe')
+ .mock(ServiceWeWantToCustomize, { prop1: true, getName: () => 'My Customized String' })
+ .mock(INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE, 'My_Token')
+
+ // All providers will be set into the TestModule.
+ .provide({
+ provide: AnythingWeWant1,
+ useValue: new TheSameAsAnyProvider(),
+ })
+ .provide({
+ provide: AnythingWeWant2,
+ useFactory: () => new TheSameAsAnyProvider(),
+ })
+ .provide(MyCustomProvider1)
+ .provide([MyCustomProvider2, MyCustomProvider3])
+
+ // Now the pipe won't be mocked.
+ .keep(PipeWeWantToRestore)
+
+ // Extra configuration.
+ .keep(MyDirective)
+ .keep(MyPipe)
+ .mock(MyService1)
+ .keep(MyService2)
+
+ // Even it belongs to the module that is marked as kept, the component will be mocked and replaced.
+ .mock(MyComponent3)
+
+ // and now we want to build our NgModule.
+ .build();
+ TestBed.configureTestingModule(ngModule);
+
+ // Extra configuration
+ TestBed.overrideTemplate(MyComponent1, 'If we need to tune testBed');
+ TestBed.overrideTemplate(MyComponent2, 'More callbacks');
+
+ return TestBed.compileComponents();
+ });
+
+ it('should render', inject([HttpBackend], (httpBackend: HttpBackend) => {
+ const fixture = MockRender(MyComponent);
+ expect(fixture).toBeDefined();
+ const content = fixture.debugElement.nativeElement.innerHTML.replace(//gm, '');
+ expect(content).toContain('My Content
');
+
+ expect(content).toContain('MyComponent1: If we need to tune testBed
');
+ expect(content).toContain('MyComponent2: More callbacks
');
+ expect(content).toContain('MyComponent3:
');
+ expect(content).toContain('ComponentWeDontWantToMock: ComponentWeDontWantToMock
');
+ expect(content).toContain('ComponentWeWantToMock:
');
+ expect(content).toContain('ComponentStructural: -$implicit- b
');
+
+ expect(content).toContain('MyDirective:
');
+ expect(content).toContain('DirectiveWeDontWantToMock:
');
+ expect(content).toContain('DirectiveWeWantToMock 1: render b');
+ expect(content).toContain('DirectiveWeWantToMock 2: render $');
+
+ expect(content).toContain('MyPipe: MyPipe:text
');
+ expect(content).toContain('PipeWeDontWantToMock: PipeWeDontWantToMock:text
');
+ expect(content).toContain('PipeWeWantToMock:
');
+ expect(content).toContain('PipeWeWantToCustomize: My Custom Result
');
+ expect(content).toContain('PipeWeWantToRestore: PipeWeWantToRestore:text
');
+
+ expect(content).toContain('INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK: INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK
');
+ expect(content).toContain('INJECTION_TOKEN_WE_WANT_TO_MOCK:
');
+ expect(content).toContain('INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE: My_Token
');
+
+ expect(content).toContain('anythingWeWant1: TheSameAsAnyProvider
');
+ expect(content).toContain('anythingWeWant2: TheSameAsAnyProvider
');
+ expect(content).toContain('myCustomProvider1: MyCustomProvider1
');
+ expect(content).toContain('myCustomProvider2: MyCustomProvider2
');
+ expect(content).toContain('myCustomProvider3: MyCustomProvider3
');
+
+ expect(content).toContain('myService1:
');
+ expect(content).toContain('myService2: MyService2
');
+ expect(content).toContain('serviceWeDontWantToMock: ServiceWeDontWantToMock
');
+ expect(content).toContain('serviceWeWantToCustomize: My Customized String
');
+ expect(content).toContain('serviceWeWantToMock:
');
+
+ // Checking that replacement works.
+ expect(httpBackend.constructor).toBeDefined();
+ expect(httpBackend.constructor.name).toEqual('HttpClientTestingBackend');
+ }));
+});
+
+describe('MockBuilder:promise', () => {
+ beforeEach(() =>
+ MockBuilder()
+ .keep(MyComponent1)
+ .keep(MyComponent2)
+
+ // In case if you need extra customization of TestBed in promise way.
+ .beforeCompileComponents(testBed => {
+ testBed.overrideTemplate(MyComponent1, 'If we need to tune testBed');
+ })
+ .beforeCompileComponents(testBed => {
+ testBed.overrideTemplate(MyComponent2, 'More callbacks');
+ })
+ );
+
+ it('should render content ignoring all dependencies', () => {
+ const fixture = MockRender('');
+ expect(fixture).toBeDefined();
+ expect(fixture.debugElement.nativeElement.innerHTML).toContain('If we need to tune testBed');
+ expect(fixture.debugElement.nativeElement.innerHTML).toContain('More callbacks');
+ });
+});
diff --git a/examples-jest/MockBuilder/fixtures.components.ts b/examples-jest/MockBuilder/fixtures.components.ts
new file mode 100644
index 0000000000..4427415110
--- /dev/null
+++ b/examples-jest/MockBuilder/fixtures.components.ts
@@ -0,0 +1,159 @@
+import { Component, ContentChild, Inject, Input, Optional, TemplateRef } from '@angular/core';
+
+import { staticFalse } from '../../tests-jest';
+
+import {
+ AnythingWeWant1,
+ AnythingWeWant2,
+ MyCustomProvider1,
+ MyCustomProvider2,
+ MyCustomProvider3,
+ MyService1,
+ MyService2,
+ ServiceWeDontWantToMock,
+ ServiceWeWantToCustomize,
+ ServiceWeWantToMock,
+} from './fixtures.services';
+import {
+ INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK,
+ INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE,
+ INJECTION_TOKEN_WE_WANT_TO_MOCK,
+} from './fixtures.tokens';
+
+@Component({
+ selector: 'component-structural',
+ template: `
+
+
+
+ `,
+})
+export class ComponentContentChild {
+ @ContentChild('block', { ...staticFalse }) injectedBlock: TemplateRef;
+ @Input() items?: T[];
+}
+
+@Component({
+ selector: 'my-component',
+ template: `
+ My Content
+
+ MyComponent1:
+ MyComponent2:
+ MyComponent3:
+ ComponentWeDontWantToMock:
+ ComponentWeWantToMock:
+
+ MyDirective:
+ DirectiveWeDontWantToMock:
+
+ DirectiveWeWantToMock 1: render {{ z.b }}
+
+
+ DirectiveWeWantToMock 2: render {{ z.a }}
+
+
+ MyPipe: {{ 'text' | MyPipe }}
+ PipeWeDontWantToMock: {{ 'text' | PipeWeDontWantToMock }}
+ PipeWeWantToMock: {{ 'text' | PipeWeWantToMock }}
+ PipeWeWantToCustomize: {{ 'text' | PipeWeWantToCustomize }}
+ PipeWeWantToRestore: {{ 'text' | PipeWeWantToRestore }}
+
+ INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK: {{ t1v }}
+ INJECTION_TOKEN_WE_WANT_TO_MOCK: {{ t2v }}
+ INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE: {{ t3v }}
+
+ anythingWeWant1: {{ anythingWeWant1?.getName() }}
+ anythingWeWant2: {{ anythingWeWant2?.getName() }}
+ myCustomProvider1: {{ myCustomProvider1?.getName() }}
+ myCustomProvider2: {{ myCustomProvider2?.getName() }}
+ myCustomProvider3: {{ myCustomProvider3?.getName() }}
+
+ myService1: {{ myService1?.getName() }}
+ myService2: {{ myService2?.getName() }}
+ serviceWeDontWantToMock: {{ serviceWeDontWantToMock?.getName() }}
+ serviceWeWantToCustomize: {{ serviceWeWantToCustomize?.getName() }}
+ serviceWeWantToMock: {{ serviceWeWantToMock?.getName() }}
+
+
+
+ ComponentStructural: {{ value }} {{ b.z }}
+
+
+ `,
+})
+export class MyComponent {
+ public readonly anythingWeWant1: AnythingWeWant1;
+ public readonly anythingWeWant2: AnythingWeWant2;
+ public readonly myCustomProvider1: MyCustomProvider1;
+ public readonly myCustomProvider2: MyCustomProvider2;
+ public readonly myCustomProvider3: MyCustomProvider3;
+ public readonly myService1: MyService1;
+ public readonly myService2: MyService2;
+ public readonly serviceWeDontWantToMock: ServiceWeDontWantToMock;
+ public readonly serviceWeWantToCustomize: ServiceWeWantToCustomize;
+ public readonly serviceWeWantToMock: ServiceWeWantToMock;
+ public readonly t1v: string;
+ public readonly t2v: string;
+ public readonly t3v: string;
+
+ constructor(
+ @Optional() @Inject(INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK) t1: string,
+ @Optional() @Inject(INJECTION_TOKEN_WE_WANT_TO_MOCK) t2: string,
+ @Optional() @Inject(INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE) t3: string,
+ @Optional() anythingWeWant1: AnythingWeWant1,
+ @Optional() anythingWeWant2: AnythingWeWant2,
+ @Optional() myCustomProvider1: MyCustomProvider1,
+ @Optional() myCustomProvider2: MyCustomProvider2,
+ @Optional() myCustomProvider3: MyCustomProvider3,
+ @Optional() myService1: MyService1,
+ @Optional() myService2: MyService2,
+ @Optional() serviceWeDontWantToMock: ServiceWeDontWantToMock,
+ @Optional() serviceWeWantToMock: ServiceWeWantToMock,
+ @Optional() serviceWeWantToCustomize: ServiceWeWantToCustomize
+ ) {
+ this.t1v = t1;
+ this.t2v = t2;
+ this.t3v = t3;
+ this.anythingWeWant1 = anythingWeWant1;
+ this.anythingWeWant2 = anythingWeWant2;
+ this.myCustomProvider1 = myCustomProvider1;
+ this.myCustomProvider2 = myCustomProvider2;
+ this.myCustomProvider3 = myCustomProvider3;
+ this.myService1 = myService1;
+ this.myService2 = myService2;
+ this.serviceWeDontWantToMock = serviceWeDontWantToMock;
+ this.serviceWeWantToCustomize = serviceWeWantToCustomize;
+ this.serviceWeWantToMock = serviceWeWantToMock;
+ }
+}
+
+@Component({
+ selector: 'component-1',
+ template: 'MyComponent1',
+})
+export class MyComponent1 {}
+
+@Component({
+ selector: 'component-2',
+ template: 'MyComponent2',
+})
+export class MyComponent2 {}
+
+@Component({
+ selector: 'component-3',
+ template: 'MyComponent3',
+})
+export class MyComponent3 {}
+
+@Component({
+ selector: 'dont-want',
+ template: 'ComponentWeDontWantToMock',
+})
+export class ComponentWeDontWantToMock {}
+
+@Component({
+ selector: 'do-want',
+ template: 'ComponentWeWantToMock',
+})
+export class ComponentWeWantToMock {}
diff --git a/examples-jest/MockBuilder/fixtures.directives.ts b/examples-jest/MockBuilder/fixtures.directives.ts
new file mode 100644
index 0000000000..6dbb2e86f8
--- /dev/null
+++ b/examples-jest/MockBuilder/fixtures.directives.ts
@@ -0,0 +1,16 @@
+import { Directive } from '@angular/core';
+
+@Directive({
+ selector: 'MyDirective',
+})
+export class MyDirective {}
+
+@Directive({
+ selector: 'WeDontWantToMock',
+})
+export class DirectiveWeDontWantToMock {}
+
+@Directive({
+ selector: '[WeWantToMock]',
+})
+export class DirectiveWeWantToMock {}
diff --git a/examples-jest/MockBuilder/fixtures.modules.ts b/examples-jest/MockBuilder/fixtures.modules.ts
new file mode 100644
index 0000000000..264824c22b
--- /dev/null
+++ b/examples-jest/MockBuilder/fixtures.modules.ts
@@ -0,0 +1,88 @@
+import { HttpClientModule } from '@angular/common/http';
+import { NgModule } from '@angular/core';
+
+import {
+ ComponentContentChild,
+ ComponentWeDontWantToMock,
+ ComponentWeWantToMock,
+ MyComponent,
+ MyComponent1,
+ MyComponent2,
+ MyComponent3,
+} from './fixtures.components';
+import { DirectiveWeDontWantToMock, DirectiveWeWantToMock, MyDirective } from './fixtures.directives';
+import {
+ MyPipe,
+ PipeWeDontWantToMock,
+ PipeWeWantToCustomize,
+ PipeWeWantToMock,
+ PipeWeWantToRestore,
+} from './fixtures.pipes';
+import {
+ MyService1,
+ MyService2,
+ ServiceWeDontWantToMock,
+ ServiceWeWantToCustomize,
+ ServiceWeWantToMock,
+} from './fixtures.services';
+import {
+ INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK,
+ INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE,
+ INJECTION_TOKEN_WE_WANT_TO_MOCK,
+} from './fixtures.tokens';
+import { CommonModule } from '@angular/common';
+
+@NgModule({
+ declarations: [
+ ComponentWeDontWantToMock,
+ ComponentWeWantToMock,
+ DirectiveWeDontWantToMock,
+ DirectiveWeWantToMock,
+ PipeWeDontWantToMock,
+ PipeWeWantToMock,
+ PipeWeWantToCustomize,
+ PipeWeWantToRestore,
+ ],
+ exports: [
+ ComponentWeDontWantToMock,
+ ComponentWeWantToMock,
+ DirectiveWeDontWantToMock,
+ DirectiveWeWantToMock,
+ PipeWeDontWantToMock,
+ PipeWeWantToMock,
+ PipeWeWantToCustomize,
+ PipeWeWantToRestore,
+ ],
+ providers: [
+ ServiceWeDontWantToMock,
+ ServiceWeWantToMock,
+ {
+ provide: INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK,
+ useValue: 'INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK',
+ },
+ {
+ provide: INJECTION_TOKEN_WE_WANT_TO_MOCK,
+ useValue: 'INJECTION_TOKEN_WE_WANT_TO_MOCK',
+ },
+ {
+ provide: INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE,
+ useValue: 'INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE',
+ },
+ ],
+})
+export class ModuleWeWantToMockBesidesMyModule {}
+
+@NgModule({
+ declarations: [MyComponent1, MyComponent2, MyComponent3, ComponentContentChild],
+ exports: [MyComponent1, MyComponent2, MyComponent3, ComponentContentChild],
+ imports: [CommonModule],
+})
+export class ModuleWeDontWantToMock {}
+
+@NgModule({
+ declarations: [MyComponent, MyDirective, MyPipe],
+ exports: [MyComponent, MyDirective, MyPipe],
+ imports: [HttpClientModule, ModuleWeWantToMockBesidesMyModule, ModuleWeDontWantToMock],
+ providers: [MyService1, MyService2, ServiceWeWantToCustomize],
+})
+export class MyModule {}
diff --git a/examples-jest/MockBuilder/fixtures.pipes.ts b/examples-jest/MockBuilder/fixtures.pipes.ts
new file mode 100644
index 0000000000..a1034148cb
--- /dev/null
+++ b/examples-jest/MockBuilder/fixtures.pipes.ts
@@ -0,0 +1,56 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'MyPipe',
+})
+export class MyPipe implements PipeTransform {
+ protected prefix = 'MyPipe:';
+
+ public transform(value: any, ...args: any[]): any {
+ return this.prefix + value;
+ }
+}
+
+@Pipe({
+ name: 'PipeWeDontWantToMock',
+})
+export class PipeWeDontWantToMock implements PipeTransform {
+ protected prefix = 'PipeWeDontWantToMock:';
+
+ public transform(value: any, ...args: any[]): any {
+ return this.prefix + value;
+ }
+}
+
+@Pipe({
+ name: 'PipeWeWantToMock',
+})
+export class PipeWeWantToMock implements PipeTransform {
+ protected prefix = 'PipeWeWantToMock:';
+
+ public transform(value: any, ...args: any[]): any {
+ return this.prefix + value;
+ }
+}
+
+@Pipe({
+ name: 'PipeWeWantToCustomize',
+})
+export class PipeWeWantToCustomize implements PipeTransform {
+ protected prefix = 'PipeWeWantToCustomize:';
+
+ public transform(value: any, ...args: any[]): any {
+ return this.prefix + value;
+ }
+}
+
+@Pipe({
+ name: 'PipeWeWantToRestore',
+})
+export class PipeWeWantToRestore implements PipeTransform {
+ protected prefix = 'PipeWeWantToRestore:';
+
+ public transform(value: any, ...args: any[]): any {
+ return this.prefix + value;
+ }
+}
diff --git a/examples-jest/MockBuilder/fixtures.services.ts b/examples-jest/MockBuilder/fixtures.services.ts
new file mode 100644
index 0000000000..4fb36c910a
--- /dev/null
+++ b/examples-jest/MockBuilder/fixtures.services.ts
@@ -0,0 +1,100 @@
+import { Injectable } from '@angular/core';
+
+@Injectable()
+export class MyService1 {
+ protected value = 'MyService1';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class MyService2 {
+ protected value = 'MyService2';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class ServiceWeDontWantToMock {
+ protected value = 'ServiceWeDontWantToMock';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class ServiceWeWantToMock {
+ protected value = 'ServiceWeWantToMock';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class ServiceWeWantToCustomize {
+ protected value = 'ServiceWeWantToCustomize';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class AnythingWeWant1 {
+ protected value = 'AnythingWeWant1';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class TheSameAsAnyProvider {
+ protected value = 'TheSameAsAnyProvider';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class AnythingWeWant2 {
+ protected value = 'AnythingWeWant2';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class MyCustomProvider1 {
+ protected value = 'MyCustomProvider1';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class MyCustomProvider2 {
+ protected value = 'MyCustomProvider2';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class MyCustomProvider3 {
+ protected value = 'MyCustomProvider3';
+
+ public getName() {
+ return this.value;
+ }
+}
diff --git a/examples-jest/MockBuilder/fixtures.tokens.ts b/examples-jest/MockBuilder/fixtures.tokens.ts
new file mode 100644
index 0000000000..8d527302f7
--- /dev/null
+++ b/examples-jest/MockBuilder/fixtures.tokens.ts
@@ -0,0 +1,7 @@
+import { InjectionToken } from '@angular/core';
+
+export const INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK = new InjectionToken('INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK');
+
+export const INJECTION_TOKEN_WE_WANT_TO_MOCK = new InjectionToken('INJECTION_TOKEN_WE_WANT_TO_MOCK');
+
+export const INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE = new InjectionToken('INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE');
diff --git a/examples-jest/MockReactiveForms/MockReactiveForms.spec.ts b/examples-jest/MockReactiveForms/MockReactiveForms.spec.ts
index e2e97f67a0..93f1440b57 100644
--- a/examples-jest/MockReactiveForms/MockReactiveForms.spec.ts
+++ b/examples-jest/MockReactiveForms/MockReactiveForms.spec.ts
@@ -31,6 +31,6 @@ describe('MockReactiveForms', () => {
spyOn(mockedReactiveFormComponent, 'writeValue');
component.formControl.setValue('bar');
- expect(mockedReactiveFormComponent.writeValue as any).toHaveBeenCalledWith('bar');
+ expect(mockedReactiveFormComponent.writeValue).toHaveBeenCalledWith('bar');
});
});
diff --git a/examples-jest/NG_MOCKS/NG_MOCKS.spec.ts b/examples-jest/NG_MOCKS/NG_MOCKS.spec.ts
new file mode 100644
index 0000000000..6c3a7cdf06
--- /dev/null
+++ b/examples-jest/NG_MOCKS/NG_MOCKS.spec.ts
@@ -0,0 +1,122 @@
+import { HttpClientModule } from '@angular/common/http';
+import { HttpClientTestingModule } from '@angular/common/http/testing';
+import { inject, TestBed } from '@angular/core/testing';
+import { isMockedNgDefOf, MockBuilder, NG_MOCKS } from 'ng-mocks';
+
+import {
+ ComponentWeDontWantToMock,
+ ComponentWeWantToMock,
+ MyComponent,
+ MyComponent1,
+ MyComponent2,
+ MyComponent3,
+} from './fixtures.components';
+import { DirectiveWeDontWantToMock, DirectiveWeWantToMock } from './fixtures.directives';
+import { ModuleWeDontWantToMock, ModuleWeWantToMockBesidesMyModule, MyModule } from './fixtures.modules';
+import { PipeWeDontWantToMock, PipeWeWantToMock, PipeWeWantToRestore } from './fixtures.pipes';
+import { ServiceWeDontWantToMock, ServiceWeWantToCustomize, ServiceWeWantToMock } from './fixtures.services';
+import {
+ INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK,
+ INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE,
+ INJECTION_TOKEN_WE_WANT_TO_MOCK,
+} from './fixtures.tokens';
+
+describe('NG_MOCKS:deep', () => {
+ beforeEach(async () => {
+ const ngModule = MockBuilder(MyComponent, MyModule)
+ .keep(ModuleWeDontWantToMock)
+ .keep(ComponentWeDontWantToMock)
+ .keep(DirectiveWeDontWantToMock)
+ .keep(PipeWeDontWantToMock)
+ .keep(ServiceWeDontWantToMock)
+ .keep(INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK)
+
+ .replace(HttpClientModule, HttpClientTestingModule)
+
+ .mock(ModuleWeWantToMockBesidesMyModule)
+ .mock(ComponentWeWantToMock)
+ .mock(DirectiveWeWantToMock)
+ .mock(PipeWeWantToMock)
+ .mock(ServiceWeWantToMock) // makes all methods an empty function
+ .mock(INJECTION_TOKEN_WE_WANT_TO_MOCK) // makes its value undefined
+
+ .mock(ServiceWeWantToCustomize, { prop1: true, getName: () => 'My Customized String' })
+ .mock(INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE, 'My_Token')
+
+ // Now the pipe won't be mocked.
+ .keep(PipeWeWantToRestore)
+
+ // Even it belongs to the module to keep it still will be mocked and replaced.
+ .mock(MyComponent3)
+
+ // and now we want to build our NgModule.
+ .build();
+ TestBed.configureTestingModule(ngModule);
+
+ // Extra configuration
+ TestBed.overrideTemplate(MyComponent1, 'If we need to tune testBed');
+ TestBed.overrideTemplate(MyComponent2, 'More callbacks');
+
+ return TestBed.compileComponents();
+ });
+
+ it('should contain mocks', inject([NG_MOCKS], (mocks: Map) => {
+ // main part
+ const myComponent = mocks.get(MyComponent);
+ expect(myComponent).toBe(MyComponent);
+ const myModule = mocks.get(MyModule);
+ expect(isMockedNgDefOf(myModule, MyModule, 'm')).toBeTruthy();
+
+ // keep
+ const componentWeDontWantToMock = mocks.get(ComponentWeDontWantToMock);
+ expect(componentWeDontWantToMock).toBe(ComponentWeDontWantToMock);
+ const directiveWeDontWantToMock = mocks.get(DirectiveWeDontWantToMock);
+ expect(directiveWeDontWantToMock).toBe(DirectiveWeDontWantToMock);
+ const pipeWeDontWantToMock = mocks.get(PipeWeDontWantToMock);
+ expect(pipeWeDontWantToMock).toBe(PipeWeDontWantToMock);
+ const serviceWeDontWantToMock = mocks.get(ServiceWeDontWantToMock);
+ expect(serviceWeDontWantToMock).toBe(ServiceWeDontWantToMock);
+ const injectionTokenWeDontWantToMock = mocks.get(INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK);
+ expect(injectionTokenWeDontWantToMock).toBe(INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK);
+
+ // replace
+ const httpClientModule = mocks.get(HttpClientModule);
+ expect(httpClientModule).toBe(HttpClientTestingModule);
+
+ // mock
+ const moduleWeWantToMockBesidesMyModule = mocks.get(ModuleWeWantToMockBesidesMyModule);
+ expect(isMockedNgDefOf(moduleWeWantToMockBesidesMyModule, ModuleWeWantToMockBesidesMyModule, 'm')).toBeTruthy();
+ const componentWeWantToMock = mocks.get(ComponentWeWantToMock);
+ expect(isMockedNgDefOf(componentWeWantToMock, ComponentWeWantToMock, 'c')).toBeTruthy();
+ const directiveWeWantToMock = mocks.get(DirectiveWeWantToMock);
+ expect(isMockedNgDefOf(directiveWeWantToMock, DirectiveWeWantToMock, 'd')).toBeTruthy();
+ const pipeWeWantToMock = mocks.get(PipeWeWantToMock);
+ expect(isMockedNgDefOf(pipeWeWantToMock, PipeWeWantToMock, 'p')).toBeTruthy();
+ const serviceWeWantToMock = mocks.get(ServiceWeWantToMock);
+ expect(serviceWeWantToMock).toBeDefined();
+ expect(serviceWeWantToMock.useValue).toBeDefined();
+ expect(serviceWeWantToMock.useValue.getName).toBeDefined();
+ expect(serviceWeWantToMock.useValue.getName()).toBeUndefined();
+ expect(mocks.has(INJECTION_TOKEN_WE_WANT_TO_MOCK)).toBeDefined();
+ expect(mocks.get(INJECTION_TOKEN_WE_WANT_TO_MOCK)).toBeUndefined();
+
+ // customize
+ const serviceWeWantToCustomize = mocks.get(ServiceWeWantToCustomize);
+ expect(serviceWeWantToCustomize).toBeDefined();
+ expect(serviceWeWantToCustomize.useValue).toBeDefined();
+ expect(serviceWeWantToCustomize.useValue.getName).toBeDefined();
+ expect(serviceWeWantToCustomize.useValue.getName()).toEqual('My Customized String');
+ expect(serviceWeWantToCustomize.useValue.prop1).toEqual(true);
+ const injectionTokenWeWantToCustomize = mocks.get(INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE);
+ expect(injectionTokenWeWantToCustomize).toBeDefined();
+ expect(injectionTokenWeWantToCustomize.useValue).toEqual('My_Token');
+
+ // restore
+ const pipeWeWantToRestore = mocks.get(PipeWeWantToRestore);
+ expect(pipeWeWantToRestore).toBe(PipeWeWantToRestore);
+
+ // mock nested
+ const myComponent3 = mocks.get(MyComponent3);
+ expect(isMockedNgDefOf(myComponent3, MyComponent3, 'c')).toBeTruthy();
+ }));
+});
diff --git a/examples-jest/NG_MOCKS/fixtures.components.ts b/examples-jest/NG_MOCKS/fixtures.components.ts
new file mode 100644
index 0000000000..a407350e61
--- /dev/null
+++ b/examples-jest/NG_MOCKS/fixtures.components.ts
@@ -0,0 +1,110 @@
+import { Component, ContentChild, Inject, Input, Optional, TemplateRef } from '@angular/core';
+
+import { staticFalse } from '../../tests-jest';
+
+import {
+ AnythingWeWant1,
+ AnythingWeWant2,
+ MyCustomProvider1,
+ MyCustomProvider2,
+ MyCustomProvider3,
+ MyService1,
+ MyService2,
+ ServiceWeDontWantToMock,
+ ServiceWeWantToCustomize,
+ ServiceWeWantToMock,
+} from './fixtures.services';
+import {
+ INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK,
+ INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE,
+ INJECTION_TOKEN_WE_WANT_TO_MOCK,
+} from './fixtures.tokens';
+
+@Component({
+ selector: 'component-structural',
+ template: '',
+})
+export class ComponentContentChild {
+ @ContentChild('block', { ...staticFalse }) injectedBlock: TemplateRef;
+ @Input() items?: T[];
+}
+
+@Component({
+ selector: 'my-component',
+ template: '',
+})
+export class MyComponent {
+ public readonly anythingWeWant1: AnythingWeWant1;
+ public readonly anythingWeWant2: AnythingWeWant2;
+ public readonly myCustomProvider1: MyCustomProvider1;
+ public readonly myCustomProvider2: MyCustomProvider2;
+ public readonly myCustomProvider3: MyCustomProvider3;
+ public readonly myService1: MyService1;
+ public readonly myService2: MyService2;
+ public readonly serviceWeDontWantToMock: ServiceWeDontWantToMock;
+ public readonly serviceWeWantToCustomize: ServiceWeWantToCustomize;
+ public readonly serviceWeWantToMock: ServiceWeWantToMock;
+ public readonly t1v: string;
+ public readonly t2v: string;
+ public readonly t3v: string;
+
+ constructor(
+ @Optional() @Inject(INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK) t1: string,
+ @Optional() @Inject(INJECTION_TOKEN_WE_WANT_TO_MOCK) t2: string,
+ @Optional() @Inject(INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE) t3: string,
+ @Optional() anythingWeWant1: AnythingWeWant1,
+ @Optional() anythingWeWant2: AnythingWeWant2,
+ @Optional() myCustomProvider1: MyCustomProvider1,
+ @Optional() myCustomProvider2: MyCustomProvider2,
+ @Optional() myCustomProvider3: MyCustomProvider3,
+ @Optional() myService1: MyService1,
+ @Optional() myService2: MyService2,
+ @Optional() serviceWeDontWantToMock: ServiceWeDontWantToMock,
+ @Optional() serviceWeWantToMock: ServiceWeWantToMock,
+ @Optional() serviceWeWantToCustomize: ServiceWeWantToCustomize
+ ) {
+ this.t1v = t1;
+ this.t2v = t2;
+ this.t3v = t3;
+ this.anythingWeWant1 = anythingWeWant1;
+ this.anythingWeWant2 = anythingWeWant2;
+ this.myCustomProvider1 = myCustomProvider1;
+ this.myCustomProvider2 = myCustomProvider2;
+ this.myCustomProvider3 = myCustomProvider3;
+ this.myService1 = myService1;
+ this.myService2 = myService2;
+ this.serviceWeDontWantToMock = serviceWeDontWantToMock;
+ this.serviceWeWantToCustomize = serviceWeWantToCustomize;
+ this.serviceWeWantToMock = serviceWeWantToMock;
+ }
+}
+
+@Component({
+ selector: 'component-1',
+ template: 'MyComponent1',
+})
+export class MyComponent1 {}
+
+@Component({
+ selector: 'component-2',
+ template: 'MyComponent2',
+})
+export class MyComponent2 {}
+
+@Component({
+ selector: 'component-3',
+ template: 'MyComponent3',
+})
+export class MyComponent3 {}
+
+@Component({
+ selector: 'dont-want',
+ template: 'ComponentWeDontWantToMock',
+})
+export class ComponentWeDontWantToMock {}
+
+@Component({
+ selector: 'do-want',
+ template: 'ComponentWeWantToMock',
+})
+export class ComponentWeWantToMock {}
diff --git a/examples-jest/NG_MOCKS/fixtures.directives.ts b/examples-jest/NG_MOCKS/fixtures.directives.ts
new file mode 100644
index 0000000000..6dbb2e86f8
--- /dev/null
+++ b/examples-jest/NG_MOCKS/fixtures.directives.ts
@@ -0,0 +1,16 @@
+import { Directive } from '@angular/core';
+
+@Directive({
+ selector: 'MyDirective',
+})
+export class MyDirective {}
+
+@Directive({
+ selector: 'WeDontWantToMock',
+})
+export class DirectiveWeDontWantToMock {}
+
+@Directive({
+ selector: '[WeWantToMock]',
+})
+export class DirectiveWeWantToMock {}
diff --git a/examples-jest/NG_MOCKS/fixtures.modules.ts b/examples-jest/NG_MOCKS/fixtures.modules.ts
new file mode 100644
index 0000000000..264824c22b
--- /dev/null
+++ b/examples-jest/NG_MOCKS/fixtures.modules.ts
@@ -0,0 +1,88 @@
+import { HttpClientModule } from '@angular/common/http';
+import { NgModule } from '@angular/core';
+
+import {
+ ComponentContentChild,
+ ComponentWeDontWantToMock,
+ ComponentWeWantToMock,
+ MyComponent,
+ MyComponent1,
+ MyComponent2,
+ MyComponent3,
+} from './fixtures.components';
+import { DirectiveWeDontWantToMock, DirectiveWeWantToMock, MyDirective } from './fixtures.directives';
+import {
+ MyPipe,
+ PipeWeDontWantToMock,
+ PipeWeWantToCustomize,
+ PipeWeWantToMock,
+ PipeWeWantToRestore,
+} from './fixtures.pipes';
+import {
+ MyService1,
+ MyService2,
+ ServiceWeDontWantToMock,
+ ServiceWeWantToCustomize,
+ ServiceWeWantToMock,
+} from './fixtures.services';
+import {
+ INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK,
+ INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE,
+ INJECTION_TOKEN_WE_WANT_TO_MOCK,
+} from './fixtures.tokens';
+import { CommonModule } from '@angular/common';
+
+@NgModule({
+ declarations: [
+ ComponentWeDontWantToMock,
+ ComponentWeWantToMock,
+ DirectiveWeDontWantToMock,
+ DirectiveWeWantToMock,
+ PipeWeDontWantToMock,
+ PipeWeWantToMock,
+ PipeWeWantToCustomize,
+ PipeWeWantToRestore,
+ ],
+ exports: [
+ ComponentWeDontWantToMock,
+ ComponentWeWantToMock,
+ DirectiveWeDontWantToMock,
+ DirectiveWeWantToMock,
+ PipeWeDontWantToMock,
+ PipeWeWantToMock,
+ PipeWeWantToCustomize,
+ PipeWeWantToRestore,
+ ],
+ providers: [
+ ServiceWeDontWantToMock,
+ ServiceWeWantToMock,
+ {
+ provide: INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK,
+ useValue: 'INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK',
+ },
+ {
+ provide: INJECTION_TOKEN_WE_WANT_TO_MOCK,
+ useValue: 'INJECTION_TOKEN_WE_WANT_TO_MOCK',
+ },
+ {
+ provide: INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE,
+ useValue: 'INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE',
+ },
+ ],
+})
+export class ModuleWeWantToMockBesidesMyModule {}
+
+@NgModule({
+ declarations: [MyComponent1, MyComponent2, MyComponent3, ComponentContentChild],
+ exports: [MyComponent1, MyComponent2, MyComponent3, ComponentContentChild],
+ imports: [CommonModule],
+})
+export class ModuleWeDontWantToMock {}
+
+@NgModule({
+ declarations: [MyComponent, MyDirective, MyPipe],
+ exports: [MyComponent, MyDirective, MyPipe],
+ imports: [HttpClientModule, ModuleWeWantToMockBesidesMyModule, ModuleWeDontWantToMock],
+ providers: [MyService1, MyService2, ServiceWeWantToCustomize],
+})
+export class MyModule {}
diff --git a/examples-jest/NG_MOCKS/fixtures.pipes.ts b/examples-jest/NG_MOCKS/fixtures.pipes.ts
new file mode 100644
index 0000000000..a1034148cb
--- /dev/null
+++ b/examples-jest/NG_MOCKS/fixtures.pipes.ts
@@ -0,0 +1,56 @@
+import { Pipe, PipeTransform } from '@angular/core';
+
+@Pipe({
+ name: 'MyPipe',
+})
+export class MyPipe implements PipeTransform {
+ protected prefix = 'MyPipe:';
+
+ public transform(value: any, ...args: any[]): any {
+ return this.prefix + value;
+ }
+}
+
+@Pipe({
+ name: 'PipeWeDontWantToMock',
+})
+export class PipeWeDontWantToMock implements PipeTransform {
+ protected prefix = 'PipeWeDontWantToMock:';
+
+ public transform(value: any, ...args: any[]): any {
+ return this.prefix + value;
+ }
+}
+
+@Pipe({
+ name: 'PipeWeWantToMock',
+})
+export class PipeWeWantToMock implements PipeTransform {
+ protected prefix = 'PipeWeWantToMock:';
+
+ public transform(value: any, ...args: any[]): any {
+ return this.prefix + value;
+ }
+}
+
+@Pipe({
+ name: 'PipeWeWantToCustomize',
+})
+export class PipeWeWantToCustomize implements PipeTransform {
+ protected prefix = 'PipeWeWantToCustomize:';
+
+ public transform(value: any, ...args: any[]): any {
+ return this.prefix + value;
+ }
+}
+
+@Pipe({
+ name: 'PipeWeWantToRestore',
+})
+export class PipeWeWantToRestore implements PipeTransform {
+ protected prefix = 'PipeWeWantToRestore:';
+
+ public transform(value: any, ...args: any[]): any {
+ return this.prefix + value;
+ }
+}
diff --git a/examples-jest/NG_MOCKS/fixtures.services.ts b/examples-jest/NG_MOCKS/fixtures.services.ts
new file mode 100644
index 0000000000..4fb36c910a
--- /dev/null
+++ b/examples-jest/NG_MOCKS/fixtures.services.ts
@@ -0,0 +1,100 @@
+import { Injectable } from '@angular/core';
+
+@Injectable()
+export class MyService1 {
+ protected value = 'MyService1';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class MyService2 {
+ protected value = 'MyService2';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class ServiceWeDontWantToMock {
+ protected value = 'ServiceWeDontWantToMock';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class ServiceWeWantToMock {
+ protected value = 'ServiceWeWantToMock';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class ServiceWeWantToCustomize {
+ protected value = 'ServiceWeWantToCustomize';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class AnythingWeWant1 {
+ protected value = 'AnythingWeWant1';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class TheSameAsAnyProvider {
+ protected value = 'TheSameAsAnyProvider';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class AnythingWeWant2 {
+ protected value = 'AnythingWeWant2';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class MyCustomProvider1 {
+ protected value = 'MyCustomProvider1';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class MyCustomProvider2 {
+ protected value = 'MyCustomProvider2';
+
+ public getName() {
+ return this.value;
+ }
+}
+
+@Injectable()
+export class MyCustomProvider3 {
+ protected value = 'MyCustomProvider3';
+
+ public getName() {
+ return this.value;
+ }
+}
diff --git a/examples-jest/NG_MOCKS/fixtures.tokens.ts b/examples-jest/NG_MOCKS/fixtures.tokens.ts
new file mode 100644
index 0000000000..8d527302f7
--- /dev/null
+++ b/examples-jest/NG_MOCKS/fixtures.tokens.ts
@@ -0,0 +1,7 @@
+import { InjectionToken } from '@angular/core';
+
+export const INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK = new InjectionToken('INJECTION_TOKEN_WE_DONT_WANT_TO_MOCK');
+
+export const INJECTION_TOKEN_WE_WANT_TO_MOCK = new InjectionToken('INJECTION_TOKEN_WE_WANT_TO_MOCK');
+
+export const INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE = new InjectionToken('INJECTION_TOKEN_WE_WANT_TO_CUSTOMIZE');
diff --git a/index.ts b/index.ts
index 62a3a89897..2623be0b14 100644
--- a/index.ts
+++ b/index.ts
@@ -1,4 +1,5 @@
export * from './lib/common';
+export * from './lib/mock-builder';
export * from './lib/mock-component';
export * from './lib/mock-declaration';
export * from './lib/mock-directive';
diff --git a/karma.conf.ts b/karma.conf.ts
index 60dd325a3e..0ec46bfae3 100644
--- a/karma.conf.ts
+++ b/karma.conf.ts
@@ -33,7 +33,7 @@ module.exports = (config: any) => {
preprocessors: {
'**/*.ts': ['karma-typescript'],
},
- reporters: ['dots', 'karma-typescript', 'kjhtml'],
+ reporters: ['kjhtml'],
singleRun: true,
karmaTypescriptConfig: {
diff --git a/lib/common/Mock.spec.ts b/lib/common/Mock.spec.ts
index eeddfcda50..34b1e2a3c2 100644
--- a/lib/common/Mock.spec.ts
+++ b/lib/common/Mock.spec.ts
@@ -1,5 +1,3 @@
-/* tslint:disable: max-classes-per-file */
-
import { Component, Directive, NgModule, Pipe, PipeTransform } from '@angular/core';
import { MockComponent } from '../mock-component';
diff --git a/lib/common/Mock.ts b/lib/common/Mock.ts
index 6b8824d41a..03bb21bc2b 100644
--- a/lib/common/Mock.ts
+++ b/lib/common/Mock.ts
@@ -1,5 +1,3 @@
-// tslint:disable:max-classes-per-file
-
import { EventEmitter } from '@angular/core';
import { ControlValueAccessor } from '@angular/forms';
@@ -73,5 +71,5 @@ export class MockControlValueAccessor extends Mock implements ControlValueAccess
this.__simulateTouch = fn;
}
- writeValue = () => {};
+ writeValue = (value: any) => {};
}
diff --git a/lib/common/decorate.ts b/lib/common/decorate.ts
index 34527fdd97..b5baa205cd 100644
--- a/lib/common/decorate.ts
+++ b/lib/common/decorate.ts
@@ -1,4 +1,6 @@
-import { ContentChild, ContentChildren, Input, Output, Query, Type, ViewChild, ViewChildren } from '@angular/core';
+import { ContentChild, ContentChildren, Input, Output, Query, ViewChild, ViewChildren } from '@angular/core';
+
+import { Type } from './lib';
// Looks like an A9 bug, that queries from @Component aren't processed.
// Also we have to pass prototype, not the class.
diff --git a/lib/common/index.ts b/lib/common/index.ts
index 7b81190dfd..808b6322d3 100644
--- a/lib/common/index.ts
+++ b/lib/common/index.ts
@@ -1,2 +1,3 @@
-export * from './mock-of.decorator';
export * from './Mock';
+export * from './lib';
+export * from './mock-of.decorator';
diff --git a/lib/common/lib.ts b/lib/common/lib.ts
new file mode 100644
index 0000000000..cf33c38673
--- /dev/null
+++ b/lib/common/lib.ts
@@ -0,0 +1,175 @@
+import { InjectionToken, ModuleWithProviders, PipeTransform, Provider } from '@angular/core';
+import { getTestBed } from '@angular/core/testing';
+
+import { MockedComponent } from '../mock-component';
+import { MockedDirective } from '../mock-directive';
+import { MockedModule } from '../mock-module';
+import { MockedPipe } from '../mock-pipe';
+
+import { ngMocksUniverse } from './ng-mocks-universe';
+import { jitReflector } from './reflect';
+
+// tslint:disable-next-line:interface-name
+export interface AbstractType extends Function {
+ prototype: T;
+}
+
+export type Type = new (...args: any[]) => T;
+
+// remove after removal of A5 support
+// tslint:disable-next-line:interface-name
+export interface NgModuleWithProviders extends ModuleWithProviders {
+ ngModule: Type;
+ providers?: Provider[];
+}
+
+export const NG_MOCKS = new InjectionToken