diff --git a/lib/mock-helper/mock-helper.default-replace.ts b/lib/mock-helper/mock-helper.default-replace.ts new file mode 100644 index 0000000000..6222d5e120 --- /dev/null +++ b/lib/mock-helper/mock-helper.default-replace.ts @@ -0,0 +1,6 @@ +import { AnyType } from '../common/core.types'; +import ngMocksUniverse from '../common/ng-mocks-universe'; + +export default (source: AnyType, destination: AnyType): void => { + ngMocksUniverse.getDefaults().set(source, destination); +}; diff --git a/lib/mock-helper/mock-helper.ts b/lib/mock-helper/mock-helper.ts index 732d5d9420..cc55bca1de 100644 --- a/lib/mock-helper/mock-helper.ts +++ b/lib/mock-helper/mock-helper.ts @@ -12,6 +12,7 @@ import mockHelperAutoSpy from './mock-helper.auto-spy'; import mockHelperDefaultExclude from './mock-helper.default-exclude'; import mockHelperDefaultKeep from './mock-helper.default-keep'; import mockHelperDefaultMock from './mock-helper.default-mock'; +import mockHelperDefaultReplace from './mock-helper.default-replace'; import mockHelperFaster from './mock-helper.faster'; import mockHelperFind from './mock-helper.find'; import mockHelperFindAll from './mock-helper.find-all'; @@ -70,6 +71,11 @@ export const ngMocks: { */ defaultMock(def: AnyType, handler?: (value: T, injector: Injector) => void | Partial): void; + /** + * @see https://github.com/ike18t/ng-mocks#ngmocksdefaultreplace + */ + defaultReplace(source: AnyType, destination: AnyType): void; + /** * @see https://github.com/ike18t/ng-mocks#making-angular-tests-faster */ @@ -259,6 +265,7 @@ export const ngMocks: { defaultExclude: mockHelperDefaultExclude, defaultKeep: mockHelperDefaultKeep, defaultMock: mockHelperDefaultMock, + defaultReplace: mockHelperDefaultReplace, faster: mockHelperFaster, find: mockHelperFind, findAll: mockHelperFindAll, diff --git a/tests/ng-mocks-default-replace-modules/fixtures.ts b/tests/ng-mocks-default-replace-modules/fixtures.ts new file mode 100644 index 0000000000..03e46f52ab --- /dev/null +++ b/tests/ng-mocks-default-replace-modules/fixtures.ts @@ -0,0 +1,35 @@ +import { Component, NgModule } from '@angular/core'; + +@Component({ + selector: 'target', + template: '{{ name }}', +}) +export class Target1Component { + public readonly name = 'target1'; +} + +@NgModule({ + declarations: [Target1Component], + exports: [Target1Component], +}) +export class Target1Module {} + +@Component({ + selector: 'target', + template: '{{ name }}', +}) +export class Target2Component { + public readonly name = 'target2'; +} + +@NgModule({ + declarations: [Target2Component], + exports: [Target2Component], +}) +export class Target2Module {} + +@NgModule({ + exports: [Target1Module], + imports: [Target1Module], +}) +export class Target3Module {} diff --git a/tests/ng-mocks-default-replace-modules/test.spec.ts b/tests/ng-mocks-default-replace-modules/test.spec.ts new file mode 100644 index 0000000000..0f22cd76f4 --- /dev/null +++ b/tests/ng-mocks-default-replace-modules/test.spec.ts @@ -0,0 +1,25 @@ +import { TestBed } from '@angular/core/testing'; +import { MockModule, MockRender, ngMocks } from 'ng-mocks'; + +import { + Target1Module, + Target2Module, + Target3Module, +} from './fixtures'; + +ngMocks.defaultReplace(Target1Module, Target2Module); + +describe('ng-mocks-default-replace-modules', () => { + beforeEach(() => { + return TestBed.configureTestingModule({ + imports: [MockModule(Target3Module)], + }); + }); + + it('replaces Target1Module with Target2Module', () => { + const fixture = MockRender(''); + expect(fixture.nativeElement.innerHTML).toEqual( + 'target2', + ); + }); +}); diff --git a/tests/ng-mocks-default-replace/test.spec.ts b/tests/ng-mocks-default-replace/test.spec.ts new file mode 100644 index 0000000000..ad9c09977b --- /dev/null +++ b/tests/ng-mocks-default-replace/test.spec.ts @@ -0,0 +1,112 @@ +import { Component, NgModule } from '@angular/core'; +import { TestBed } from '@angular/core/testing'; +import { + MockBuilder, + MockComponent, + MockModule, + MockRender, + ngMocks, +} from 'ng-mocks'; + +@Component({ + selector: 'target', + template: '{{ name }}', +}) +class TargetComponent { + public readonly name = 'target'; +} + +@Component({ + selector: 'target', + template: '{{ name }}', +}) +class FakeComponent { + public readonly name = 'fake'; +} + +@NgModule({ + declarations: [TargetComponent], + exports: [TargetComponent], +}) +class TargetModule {} + +ngMocks.defaultReplace(TargetComponent, FakeComponent); + +describe('ng-mocks-default-replace', () => { + describe('MockComponent', () => { + beforeEach(() => + TestBed.configureTestingModule({ + declarations: [MockComponent(TargetComponent)], + }), + ); + + it('works as usual', () => { + const fixture = MockRender(''); + expect(fixture.nativeElement.innerHTML).toEqual( + '', + ); + }); + }); + + describe('MockModule', () => { + beforeEach(() => + TestBed.configureTestingModule({ + imports: [MockModule(TargetModule)], + }), + ); + + it('replaces out of the box', () => { + const fixture = MockRender(''); + expect(fixture.nativeElement.innerHTML).toEqual( + 'fake', + ); + }); + }); + + describe('MockBuilder:default', () => { + beforeEach(() => MockBuilder(null, TargetModule)); + + it('replaces out of the box', () => { + const fixture = MockRender(''); + expect(fixture.nativeElement.innerHTML).toEqual( + 'fake', + ); + }); + }); + + describe('MockBuilder:exclude', () => { + beforeEach(() => + MockBuilder(null, TargetModule).exclude(TargetComponent), + ); + + it('switches to exclude', () => { + expect(() => MockRender('')).toThrow(); + }); + }); + + describe('MockBuilder:mock', () => { + beforeEach(() => + MockBuilder(null, TargetModule).mock(TargetComponent), + ); + + it('switches to mock', () => { + const fixture = MockRender(''); + expect(fixture.nativeElement.innerHTML).toEqual( + '', + ); + }); + }); + + describe('MockBuilder:keep', () => { + beforeEach(() => + MockBuilder(null, TargetModule).keep(TargetComponent), + ); + + it('switches to keep', () => { + const fixture = MockRender(''); + expect(fixture.nativeElement.innerHTML).toEqual( + 'target', + ); + }); + }); +});