File

projects/ng-magic-test-bed/src/test-bed/ng-magic-test-bed.class.ts

Index

Methods

Constructor

constructor(initialConfig: TestModuleMetadata)
Parameters :
Name Type Optional Description
initialConfig TestModuleMetadata No

initial config which will be extended by the other methods of this NgMagicSetupTestBed instance. The final config will be used to call TestBed.configureTestingModule implicitly by calling e.g. .injection()

Methods

Public componentMocks
componentMocks(componentClass: Type)
Type parameters :
  • C

declare that you want to generically mock all inputs and outputs of a component and retrieve all created component mock instances after fixture creation.

Parameters :
Name Type Optional Description
componentClass Type<C> No

class of the component that should be mocked in the fixture.

Returns : Array<C>

an array of all component instances that were found statically inside the fixture. The array's members can only be used after calling .fixture(). Before that time the array is initialized like this: ['this array can only be used after fixture() was called'].

Public componentProviderMock
componentProviderMock(componentClass: Type, token: ProviderToken, mock?: M, dontSpy, spySource?: AbstractType>)
Type parameters :
  • S
  • M

If you have component provides a provider you can mock it using this method.

Parameters :
Name Type Optional Default value Description
componentClass Type<any> No

the componentClass is the reference of the class of your angular component.

token ProviderToken<S> No

the provider token that you want to mock

mock M Yes

the mock

dontSpy No false

optional parameter to prevent the default spy creation on the mock

spySource AbstractType<Partial<S>> Yes
Returns : |
Public componentServiceMock
componentServiceMock(componentClass: Type, serviceClass: AbstractType, mock: M, dontSpy)
Type parameters :
  • S
  • M
Parameters :
Name Type Optional
componentClass Type<any> No
serviceClass AbstractType<S> No
mock M No
dontSpy No
Public componentServiceMock
componentServiceMock(componentClass: Type, serviceClass: AbstractType, mock: M)
Type parameters :
  • S
  • M
Parameters :
Name Type Optional
componentClass Type<any> No
serviceClass AbstractType<S> No
mock M No
Public componentServiceMock
componentServiceMock(componentClass: Type, serviceClass: AbstractType)
Type parameters :
  • S
  • M
Parameters :
Name Type Optional
componentClass Type<any> No
serviceClass AbstractType<S> No
Returns : SpyObj<S>
Public componentServiceMock
componentServiceMock(componentClass: Type, serviceClass: AbstractType, mock?: M, dontSpy?: boolean)
Type parameters :
  • S
  • M

If you have component that provides a service you can mock it using this method.

Parameters :
Name Type Optional Description
componentClass Type<any> No

the componentClass is the reference of the class of your angular component.

serviceClass AbstractType<S> No

the serviceClass is the reference to the class of the service that you want to mock

mock M Yes

the mock mocks the service and should implement a partial of the service class

dontSpy boolean Yes

optional parameter to prevent the default spy creation on the mock using the prototype of the serviceClass

Returns : |
Public declaration
declaration(declaration: any)
Parameters :
Name Type Optional Description
declaration any No

declaration will be pushed to the declarations of the testing module config. check out angular docs for more information https://angular.io/guide/testing-services#angular-testbed https://angular.io/api/core/testing/TestBed#configuretestingmodule https://angular.io/api/core/testing/TestModuleMetadata

Returns : void
Public declarations
declarations(declarations: Array)
Parameters :
Name Type Optional Description
declarations Array<any> No

declarations will be pushed to the declarations of the testing module config. check out angular docs for more information https://angular.io/guide/testing-services#angular-testbed https://angular.io/api/core/testing/TestBed#configuretestingmodule https://angular.io/api/core/testing/TestModuleMetadata

Returns : void
Public directiveMocks
directiveMocks(directiveClass: Type)
Type parameters :
  • C

declare that you want to mock a directive for a selector and retrieve all created component mock instances after fixture creation. Note that this method behaves different to directiveMocks. This is because Angular is missing a public reflectDirectiveType method. This method will be made smarter as soon as such a method is available.

Parameters :
Name Type Optional Description
directiveClass Type<C> No

class of the directive that should be used in the fixture for a specific selector you want to mock.

Returns : Array<C>

an array of all component instances that were found statically inside the fixture. The array's members can only be used after calling .fixture(). Before that time the array is initialized like this: ['this array can only be used after fixture() was called'].

Public directiveProviderMock
directiveProviderMock(directiveClass: Type, token: ProviderToken, mock?: M, dontSpy, spySource?: AbstractType)
Type parameters :
  • S
  • M

If you have directive that provides a provider you can mock it using this method.

Parameters :
Name Type Optional Default value Description
directiveClass Type<any> No

the directiveClass is the reference of the class of your angular directive.

token ProviderToken<S> No

the provider token that you want to mock

mock M Yes

the mock

dontSpy No false

optional parameter to prevent the default spy creation on the mock

spySource AbstractType<any> Yes
Returns : |
Public directiveServiceMock
directiveServiceMock(directiveClass: Type, serviceClass: AbstractType, mock: M, dontSpy)
Type parameters :
  • S
  • M

If you have directive that provides a service you can mock it using this method.

Parameters :
Name Type Optional Description
directiveClass Type<any> No

the directiveClass is the reference of the class of your angular directive.

serviceClass AbstractType<S> No

the serviceClass is the reference to the class of the service that you want to mock

mock M No

the mock mocks the service and should implement a partial of the service class

dontSpy No

optional parameter to prevent the default spy creation on the mock using the prototype of the serviceClass

Public directiveServiceMock
directiveServiceMock(directiveClass: Type, serviceClass: AbstractType, mock: M)
Type parameters :
  • S
  • M
Parameters :
Name Type Optional
directiveClass Type<any> No
serviceClass AbstractType<S> No
mock M No
Public directiveServiceMock
directiveServiceMock(directiveClass: Type, serviceClass: AbstractType)
Type parameters :
  • S
  • M
Parameters :
Name Type Optional
directiveClass Type<any> No
serviceClass AbstractType<S> No
Returns : SpyObj<S>
Public directiveServiceMock
directiveServiceMock(directiveClass: Type, serviceClass: AbstractType, mock?: M, dontSpy?: boolean)
Type parameters :
  • S
  • M
Parameters :
Name Type Optional
directiveClass Type<any> No
serviceClass AbstractType<S> No
mock M Yes
dontSpy boolean Yes
Returns : |
Public factoryMock
factoryMock(factoryClass: AbstractType, instances: Array<>)
Type parameters :
  • I
  • F
  • M

mocks a service that has a "create" method.

Parameters :
Name Type Optional Description
factoryClass AbstractType<F> No

service that has a "create" method that you want to mock.

instances Array<> No

will be returned by the mock this method return when "create" is called. The first call of mock.create() will return the first item in the instances-array and so on.

Returns : SpyObj<F>

a mock for the factory. mock.create will return the one of the given instances every time it is called

Public fixture
fixture(componentClass: Type, initialInputs: MagicFixtureInputs, disableNoErrorSchema)
Type parameters :
  • C

Use this method to create a component fixture. This method may only be called once per NgMagicTestBed instance.

Parameters :
Name Type Optional Default value Description
componentClass Type<C> No

class of the root component you want to compile and create.

initialInputs MagicFixtureInputs<C> No {}

values applied to the component's inputs before the first detectChanges(), via ComponentRef.setInput() - works for both classic

disableNoErrorSchema No false

by default the NgMagicTestBed uses the NO_ERROR_SCHEMA of angular to prevent the compiler from throwing exceptions e.g. for missing or unknown inputs.

Returns : ComponentFixture<C>

a component fixture like standard TestBed.createComponent(componentClass) would have returned it.

Public import
import(aImport: any)
Parameters :
Name Type Optional
aImport any No
Returns : void
Public imports
imports(imports: any[])
Parameters :
Name Type Optional Description
imports any[] No

imports will be pushed to the imports of the testing module config. check out angular docs for more information https://angular.io/guide/testing-services#angular-testbed https://angular.io/api/core/testing/TestBed#configuretestingmodule https://angular.io/api/core/testing/TestModuleMetadata

Returns : void
Public injection
injection(token: ProviderToken)
Type parameters :
  • S

return you the service or provider for a given token from the angular dependency injection. This will trigger the TestBed configureTestingModule step. After this step you can not create any more mocks. Make sure you create all your mocks before calling this method.

Parameters :
Name Type Optional Description
token ProviderToken<S> No

of the provider that you want to inject

Returns : S

whatever angular dependency injection finds for your token

Public interfaceMock
interfaceMock(mock: I, dontSpy)
Type parameters :
  • I

Creates a mock object that satisfies the shape of a TypeScript interface I. This does not (and cannot) replace I anywhere - interfaces have no runtime representation, so there is no prototype to reflect on the way objectMock() reflects on a class. This means every member of I has to be supplied in mock - only the methods you actually provide become spies, nothing can be auto-generated for the ones you omit. Use this instead of objectMock(undefined, mock) purely to avoid casting the result to I & SpyObj yourself.

Parameters :
Name Type Optional Default value Description
mock I No

an object implementing every member of I.

dontSpy No false

optional parameter to prevent the default spy creation on the mock.

Public keptComponentImports
keptComponentImports(keptComponentImports: Array>)

Declare that you want to keep several pipes/directives/standalone components exactly as they are, in one call. Each one is added to the imports (or declarations, for non-standalone classes) of your fixture component and all other kept components - the same effect as calling keptPipe() once per item, but without the per-item boilerplate and without querying for instances afterward. Typical use: keeping Angular's own structural directives/pipes (NgIf, NgFor, AsyncPipe, ...) that your fixture component's template relies on, since overriding a standalone component's imports for fixture/mock purposes replaces its imports array entirely - see keptDirectives()/keptComponents() if you also need access to the rendered instances afterward.

Parameters :
Name Type Optional Description
keptComponentImports Array<Type<any>> No

array of pipe/directive/component classes to keep as their real implementation.

Returns : void
Public keptComponents
keptComponents(componentClass: Type)
Type parameters :
  • C

Declare that you want to keep a certain component. This kept component will be added to the imports of your fixture component and all other kept components.

Parameters :
Name Type Optional
componentClass Type<C> No
Returns : Array<C>

an array of all component instances that were found statically inside the fixture. The array's members can only be used after calling .fixture(). Before that time the array is initialized like this: ['this array can only be used after fixture() was called'].

Public keptDirectives
keptDirectives(directiveClass: Type)
Type parameters :
  • C

Declare that you want to keep a certain directive. This kept directive will be added to the imports of your fixture component and all kept components.

Parameters :
Name Type Optional
directiveClass Type<C> No
Returns : Array<C>
Public keptPipe
keptPipe(pipeClass: Type)
Type parameters :
  • C

declare that you want to keep a pipe for a selector.

Parameters :
Name Type Optional Description
pipeClass Type<C> No

class of the pipe that you want to keep to use it in your fixture and all kept components.

Returns : void
Public objectMock
objectMock(objectClass: AbstractType, mock: M, dontSpy)
Type parameters :
  • O
  • M

Can be used to create a mock for an object that should not be registered at angular TestBed.

Parameters :
Name Type Optional Description
objectClass AbstractType<O> No

This class' prototype will be used to extend the result mock by a spy for each method on the prototype.

mock M No

An object that should implement partial of objectClass and contain all methods that you want to return something.

dontSpy No

optional parameter to prevent the default spy creation on the mock.

Public objectMock
objectMock(objectClass: AbstractType, mock: M)
Type parameters :
  • O
  • M
Parameters :
Name Type Optional
objectClass AbstractType<O> No
mock M No
Public objectMock
objectMock(objectClass: undefined, mock: M)
Type parameters :
  • O
  • M
Parameters :
Name Type Optional
objectClass undefined No
mock M No
Returns : SpyObj<M>
Public objectMock
objectMock(objectClass: AbstractType | undefined, mock: M | any, dontSpy)
Type parameters :
  • O
  • M
Parameters :
Name Type Optional Default value
objectClass AbstractType<O> | undefined No
mock M | any No
dontSpy No false
Returns : |
Public observer
observer(observable: Observable, name?: string)
Type parameters :
  • T

Subscribes to a given observable and spies on its states and emitted values.

Parameters :
Name Type Optional Description
observable Observable<T> No

Observable you want to spy

name string Yes

Optional name that prefixes all spies that are created by the observer. This makes it easier to read the test output if anything fails.

Returns : SpyObserver<T>

observer that can be used to make assertions in your test cases e.g.: expect(observer.next).toHaveBeenCalledWith(expectedValue); For more information check SpyObserver documentation

Public outputObserver
outputObserver(output: OutputEmitterRef, name?: string)
Type parameters :
  • T

Subscribes to a given output and spies on its states and emitted values.

Parameters :
Name Type Optional Description
output OutputEmitterRef<T> No

Output you want to spy

name string Yes

Optional name that prefixes all spies that are created by the observer. This makes it easier to read the test output if anything fails.

Returns : SpyObserver<T>

outputObserver that can be used to make assertions in your test cases e.g.: expect(outputObserver.next).toHaveBeenCalledWith(expectedValue); For more information check SpyObserver documentation

Public pipeMock
pipeMock(pipeName: string, transform?: (value?: any) => void)
Type parameters :
  • C

declare that you want to mock a pipe for a selector.

Parameters :
Name Type Optional
pipeName string No
transform function Yes
Returns : Spy
Public provider
provider(provider: any)
Parameters :
Name Type Optional Description
provider any No

import will be pushed to the providers of the testing module config. check out angular docs for more information https://angular.io/guide/testing-services#angular-testbed https://angular.io/api/core/testing/TestBed#configuretestingmodule https://angular.io/api/core/testing/TestModuleMetadata

Returns : void
Public providerFunctionMock
providerFunctionMock(token: InjectionToken, callback?)
Type parameters :
  • F

replaces a function that is provided with an angular provider token with a spy

Parameters :
Name Type Optional Description
token InjectionToken<F> No

token that is used to provide a function

callback Yes

optional parameter to define default behavior for the mocked provider function

Returns : Spy<F>

spy on the mocked provider function

Public providerMock
providerMock(token: ProviderToken, mock: M, dontSpy: boolean, spySource?: AbstractType>)
Type parameters :
  • S
  • M

mocks a provider for a given token with a given mock. If wanted your mock can be extended by spies from a given spySource class.

Parameters :
Name Type Optional Default value Description
token ProviderToken<S> No

token for provider provision

mock M No

mock that will be registered for the token

dontSpy boolean No false

optional parameter to prevent the default spy creation on the mock.

spySource AbstractType<Partial<S>> Yes

for each method in spySources prototype an additional spy will be created on the mock

Returns : |

Your mocks methods will be overwritten with spies that call through to the mocks methods like spyOn method of your test framework. In addition to that a spy will be added for each additional method that was found on the objectClass' prototype.

Public providers
providers(providers: any[])
Parameters :
Name Type Optional Description
providers any[] No

providers will be pushed to the providers of the testing module config. check out angular docs for more information https://angular.io/guide/testing-services#angular-testbed https://angular.io/api/core/testing/TestBed#configuretestingmodule https://angular.io/api/core/testing/TestModuleMetadata

Returns : void
Public run
run()

Can be used to run a callback in injection context. Like TestBed.runInInjectionContext(). Additionally this will trigger the TestBed configureTestingModule step. After this step you can not create any more mocks. Make sure you create all your mocks before calling this method. This method can be used to configure the testing module when used without

Returns : void

what

Public run
run(callbackToBeRunInInjectionContext: () => void)
Type parameters :
  • T
Parameters :
Name Type Optional
callbackToBeRunInInjectionContext function No
Returns : T
Public run
run(callbackToBeRunInInjectionContext?: () => void)
Type parameters :
  • T
Parameters :
Name Type Optional
callbackToBeRunInInjectionContext function Yes
Returns : T
Public schema
schema(schema: SchemaMetadata | any[])
Parameters :
Name Type Optional Description
schema SchemaMetadata | any[] No

schema will be pushed to the schemas of the testing module config. Note that the NO_ERRORS_SCHEMA is pushed by default. This can be disabled when calling .fixture(). check out angular docs for more information https://angular.io/guide/testing-services#angular-testbed https://angular.io/api/core/testing/TestBed#configuretestingmodule https://angular.io/api/core/testing/TestModuleMetadata

Returns : void
Public schemas
schemas(schemas: Array)
Parameters :
Name Type Optional Description
schemas Array<SchemaMetadata | []> No

schemas will be pushed to the schemas of the testing module config. Note that the NO_ERRORS_SCHEMA is pushed by default. This can be disabled when calling .fixture(). check out angular docs for more information https://angular.io/guide/testing-services#angular-testbed https://angular.io/api/core/testing/TestBed#configuretestingmodule https://angular.io/api/core/testing/TestModuleMetadata

Returns : void
Public serviceMock
serviceMock(serviceClass: AbstractType, mock: M, dontSpy)
Type parameters :
  • S
  • M
Parameters :
Name Type Optional
serviceClass AbstractType<S> No
mock M No
dontSpy No
Public serviceMock
serviceMock(serviceClass: AbstractType, mock: M)
Type parameters :
  • S
  • M
Parameters :
Name Type Optional
serviceClass AbstractType<S> No
mock M No
Public serviceMock
serviceMock(serviceClass: AbstractType)
Type parameters :
  • S
  • M
Parameters :
Name Type Optional
serviceClass AbstractType<S> No
Returns : SpyObj<S>
Public serviceMock
serviceMock(serviceClass: AbstractType, mock?: M, dontSpy?: boolean)
Type parameters :
  • S
  • M

mocks a service with the given mock

Parameters :
Name Type Optional Description
serviceClass AbstractType<S> No

service that you want to mock

mock M Yes

that should mock the service. All methods on the mock will become spies. For each method on serviceClass' prototype another spy will be added to the mock.

dontSpy boolean Yes

optional parameter to prevent the default spy creation on the mock.

Returns : |

the mock after creating some spies on it (if not disabled)

import { TestBed, TestModuleMetadata, ComponentFixture } from '@angular/core/testing';
import { SchemaMetadata, Type, AbstractType, Pipe, InjectionToken, ProviderToken, OutputEmitterRef } from '@angular/core';
import { createSpy, Func, Spy, SpyObj } from '../spy-framework/spy-framework';
import { Observable } from 'rxjs';
import { observe } from '../observe/observe.function';
import { SpyObserver } from '../observe/spy-observer.class';
import { outputToObservable } from '@angular/core/rxjs-interop';
import { TestBedConfigurator } from './test-bed-configurator.class';
import { IFactory } from './i-factory.interface';
import { mockComponent } from '../public-api';
import { MagicFixtureInputs } from './magic-fixture-inputs.type';


export class NgMagicTestBed  {

    /**
    * @ignore
    */
    private configurator: TestBedConfigurator;

    /**
    * @param initialConfig  initial config which will be extended by the other methods of this NgMagicSetupTestBed instance.
    *  The final config will be used to call TestBed.configureTestingModule implicitly by
    * calling e.g. .injection()
    */
    constructor(initialConfig: TestModuleMetadata = {}) {
        this.configurator = new TestBedConfigurator(initialConfig);
    }

    /**
    * @param declarations declarations will be pushed to the declarations of the testing module config.
    * check out angular docs for more information
    * https://angular.io/guide/testing-services#angular-testbed
    * https://angular.io/api/core/testing/TestBed#configuretestingmodule
    * https://angular.io/api/core/testing/TestModuleMetadata
    */
    public declarations(declarations: Array<any>) {
        this.configurator.declarations(declarations);
    }

    /**
    * @param declaration declaration will be pushed to the declarations of the testing module config.
    * check out angular docs for more information
    * https://angular.io/guide/testing-services#angular-testbed
    * https://angular.io/api/core/testing/TestBed#configuretestingmodule
    * https://angular.io/api/core/testing/TestModuleMetadata
    */
    public declaration(declaration: any) {
          this.configurator.declarations([declaration]);
    }

    /**
    * @param schemas schemas will be pushed to the schemas of the testing module config. Note that the NO_ERRORS_SCHEMA
    * is pushed by default. This can be disabled when calling .fixture().
    * check out angular docs for more information
    * https://angular.io/guide/testing-services#angular-testbed
    * https://angular.io/api/core/testing/TestBed#configuretestingmodule
    * https://angular.io/api/core/testing/TestModuleMetadata
    */
    public schemas(schemas: Array<SchemaMetadata | any[]>) {
           this.configurator.schemas(schemas);
    }

    /**
    * @param schema schema will be pushed to the schemas of the testing module config. Note that the NO_ERRORS_SCHEMA
    * is pushed by default. This can be disabled when calling .fixture().
    * check out angular docs for more information
    * https://angular.io/guide/testing-services#angular-testbed
    * https://angular.io/api/core/testing/TestBed#configuretestingmodule
    * https://angular.io/api/core/testing/TestModuleMetadata
    */
    public schema(schema: SchemaMetadata | any[]) {
          this.configurator.schemas([schema]);
    }

    /**
    * @param imports imports will be pushed to the imports of the testing module config.
    * check out angular docs for more information
    * https://angular.io/guide/testing-services#angular-testbed
    * https://angular.io/api/core/testing/TestBed#configuretestingmodule
    * https://angular.io/api/core/testing/TestModuleMetadata
    */
    public imports(imports: any[]) {
        this.configurator.imports(imports);
    }

    /**
    * @param imports import will be pushed to the imports of the testing module config.
    * check out angular docs for more information
    * https://angular.io/guide/testing-services#angular-testbed
    * https://angular.io/api/core/testing/TestBed#configuretestingmodule
    * https://angular.io/api/core/testing/TestModuleMetadata
    */
    public import(aImport: any) {
           this.configurator.imports([aImport]);
    }

    /**
     * Declare that you want to keep several pipes/directives/standalone components exactly as they are,
     * in one call. Each one is added to the imports (or declarations, for non-standalone classes) of your
     * fixture component and all other kept components - the same effect as calling keptPipe() once per
     * item, but without the per-item boilerplate and without querying for instances afterward.
     * Typical use: keeping Angular's own structural directives/pipes (NgIf, NgFor, AsyncPipe, ...) that
     * your fixture component's template relies on, since overriding a standalone component's imports for
     * fixture/mock purposes replaces its imports array entirely - see keptDirectives()/keptComponents() if
     * you also need access to the rendered instances afterward.
     * @param keptComponentImports array of pipe/directive/component classes to keep as their real implementation.
     */
    public keptComponentImports(keptComponentImports: Array<Type<any>>){
        keptComponentImports.forEach(keptComponentImport =>  this.configurator.addToImportsOrDeclarations(keptComponentImport))
    }

    /**
    * @param providers providers will be pushed to the providers of the testing module config.
    * check out angular docs for more information
    * https://angular.io/guide/testing-services#angular-testbed
    * https://angular.io/api/core/testing/TestBed#configuretestingmodule
    * https://angular.io/api/core/testing/TestModuleMetadata
    */
    public providers(providers: any[]) {
        this.configurator.providers(providers);
    }

    /**
    * @param provider import will be pushed to the providers of the testing module config.
    * check out angular docs for more information
    * https://angular.io/guide/testing-services#angular-testbed
    * https://angular.io/api/core/testing/TestBed#configuretestingmodule
    * https://angular.io/api/core/testing/TestModuleMetadata
    */
    public provider(provider: any) {
         this.configurator.providers([provider]);
    }

    /**
    * If you have directive that provides a service you can mock it using this method.
    * @param directiveClass the directiveClass is the reference of the class of your angular directive.
    * @param serviceClass the serviceClass is the reference to the class of the service that you want to mock
    * @param mock the mock mocks the service and should implement a partial of the service class
    * @param dontSpy optional parameter to prevent the default spy creation on the mock using the prototype of the serviceClass
    */
    public directiveServiceMock<S, M extends Partial<S>>(directiveClass: Type<any>, serviceClass: AbstractType<S>, mock: M,
        dontSpy: true): S & M;
    public directiveServiceMock<S, M extends Partial<S>>(directiveClass: Type<any>, serviceClass: AbstractType<S>, mock: M):
        SpyObj<S> & SpyObj<M>;
    public directiveServiceMock<S, M extends Partial<S>>(directiveClass: Type<any>, serviceClass: AbstractType<S>):
        SpyObj<S>;
    public directiveServiceMock<S, M extends Partial<S>>(directiveClass: Type<any>, serviceClass: AbstractType<S>,
        mock?: M, dontSpy?: boolean):
        S & M | SpyObj<S> & SpyObj<M> {
           return this.directiveProviderMock(directiveClass, serviceClass, mock, dontSpy, serviceClass)
    }

    /**
    *  If you have directive that provides a provider you can mock it using this method.
    * @param directiveClass the directiveClass is the reference of the class of your angular directive.
    * @param token the provider token that you want to mock
    * @param mock the mock
    * @param dontSpy optional parameter to prevent the default spy creation on the mock
    */
    public directiveProviderMock<S, M extends Partial<S>>(directiveClass: Type<any>, token: ProviderToken<S>, mock?: M, dontSpy = false,
        spySource?: AbstractType<any>):  S & M | SpyObj<S> & SpyObj<M> {
        return this.configurator.uiThingProviderMock('overrideDirective', directiveClass, token, mock, dontSpy, spySource);
    }


    public componentServiceMock<S, M extends Partial<S>>(componentClass: Type<any>, serviceClass: AbstractType<S>, mock: M,
        dontSpy: true): S & M;
    public componentServiceMock<S, M extends Partial<S>>(componentClass: Type<any>, serviceClass: AbstractType<S>, mock: M):
        SpyObj<S> & SpyObj<M>;
    public componentServiceMock<S, M extends Partial<S>>(componentClass: Type<any>, serviceClass: AbstractType<S>):
        SpyObj<S>;
    /**
    *  If you have component that provides a service you can mock it using this method.
    * @param componentClass the componentClass is the reference of the class of your angular component.
    * @param serviceClass the serviceClass is the reference to the class of the service that you want to mock
    * @param mock the mock mocks the service and should implement a partial of the service class
    * @param dontSpy optional parameter to prevent the default spy creation on the mock using the prototype of the serviceClass
    */
    public componentServiceMock<S, M extends Partial<S>>(componentClass: Type<any>, serviceClass: AbstractType<S>,
        mock?: M, dontSpy?: boolean):
        S & M | SpyObj<S> & SpyObj<M> {
        return this.componentProviderMock(componentClass, serviceClass, mock, dontSpy, serviceClass);
    }

    /**
    *  If you have component provides a provider you can mock it using this method.
    * @param componentClass the componentClass is the reference of the class of your angular component.
    * @param token the provider token that you want to mock
    * @param mock the mock
    * @param dontSpy optional parameter to prevent the default spy creation on the mock
    */
    public componentProviderMock<S, M extends Partial<S>>(componentClass: Type<any>, token: ProviderToken<S>, mock?: M, dontSpy = false,
        spySource?: AbstractType<Partial<S>>): S & M | SpyObj<S> & SpyObj<M>{
        return this.configurator.uiThingProviderMock('overrideComponent', componentClass, token, mock, dontSpy, spySource);
    }


    /**
    *  declare that you want to mock a directive for a selector and retrieve all created component mock instances after fixture
    * creation.
    * Note that this method behaves different to directiveMocks. This is because Angular is missing a public reflectDirectiveType method. 
    * This method will be made smarter as soon as such a method is available.
    * @param directiveClass class of the directive that should be used in the fixture for a specific selector you want to mock.
    * @returns an array of all component instances that were found statically inside the fixture. The array's members can only be
    * used after calling .fixture(). Before that time the array is initialized like this:
    * ['this array can only be used after fixture() was called'].
    */
    public directiveMocks<C>(directiveClass: Type<C>): Array<C> {
        return this.configurator.useInFixtureAndQueryInstances(directiveClass);
    }

    /**
     * declare that you want to mock a pipe for a selector.
     * @param pipeClass class of the pipe that should be used in the fixture and all other kept components for a specific pipe selector that you want to mock.
     */
    public pipeMock<C>(pipeName: string, transform?: (value: any)=> any): Spy{
        if (!pipeName){
            throw new Error('pipeName has to be defined');
        }
        const defaultTransform = (transformValue: any) => transformValue;
        const spy = createSpy('transform', transform ?? defaultTransform);
        const PipeMock = class { transform(value: any){
            return spy(value);
        }}
        Pipe({name: pipeName, standalone: true})(PipeMock) 
        this.configurator.addToImportsOrDeclarations(PipeMock);
        return spy;
    }

    /**
     * declare that you want to keep a pipe for a selector.
     * @param pipeClass class of the pipe that you want to keep to use it in your fixture and all kept components.
     */
    public keptPipe<C>(pipeClass: Type<C>){
        this.configurator.addToImportsOrDeclarations(pipeClass);
    }

    /**
     * Declare that you want to keep a certain directive. This kept directive will be added to the imports of your fixture component and all kept components.
     * @param directiveClass 
     * @returns 
     */
    public keptDirectives<C>(directiveClass: Type<C>): Array<C> {
        return this.directiveMocks(directiveClass);
    }

    /**
     * Declare that you want to keep a certain component. This kept component will be added to the imports of your fixture component and all other kept components.
     * @param componentClass 
     * @returns an array of all component instances that were found statically inside the fixture. The array's members can only be
    * used after calling .fixture(). Before that time the array is initialized like this:
    * ['this array can only be used after fixture() was called'].
     */
    public keptComponents<C>(componentClass: Type<C>): Array<C> {
        return this.configurator.keptComponents(componentClass);
    }

    /**
    * declare that you want to generically mock all inputs and outputs of a component and retrieve all created component mock instances after fixture
    * creation.
    * @param componentClass class of the component that should be mocked in the fixture.
    * @returns an array of all component instances that were found statically inside the fixture. The array's members can only be
    * used after calling .fixture(). Before that time the array is initialized like this:
    * ['this array can only be used after fixture() was called'].
    */
    public componentMocks<C>(componentClass: Type<C>): Array<C> {
        const componentMock = mockComponent(componentClass);
        return this.configurator.useInFixtureAndQueryInstances(componentMock);
    }

    /**
    *  Use this method to create a component fixture. This method may only be called once per NgMagicTestBed instance.
    * @param componentClass class of the root component you want to compile and create.
    * @param initialInputs values applied to the component's inputs before the first detectChanges(), via
    * ComponentRef.setInput() - works for both classic @Input()-decorated properties and signal-based input()
    * properties. For a signal input created with a `transform`, provide the transform's input type (the same
    * type you'd write in a template binding) - it will be transformed the same way Angular does for real bindings.
    * @param disableNoErrorSchema by default the NgMagicTestBed uses the NO_ERROR_SCHEMA of angular to prevent the compiler from
    * throwing exceptions e.g. for missing or unknown inputs.
    * @returns a component fixture like standard TestBed.createComponent(componentClass) would have returned it.
    */
    public fixture<C>(componentClass: Type<C>, initialInputs: MagicFixtureInputs<C> = {}, disableNoErrorSchema = false): ComponentFixture<C> {
        return this.configurator.fixture(componentClass, initialInputs, disableNoErrorSchema);
    }

    /**
     * Can be used to create a mock for an object that should not be registered at angular TestBed.
     * @param objectClass This class' prototype will be used to extend the result mock by a spy for each method on the prototype.
     * @param mock An object that should implement partial of objectClass and contain all methods that you want to return something.
     * @param dontSpy optional parameter to prevent the default spy creation on the mock.
     * @returns Your mocks methods will be overwritten with spies that call through to the mocks methods like spyOn method of your test framework.
     * In addition to that a spy will be added for each additional method that was found on the objectClass' prototype.
     */
    public objectMock<O, M extends Partial<O>>(objectClass: AbstractType<O>, mock: M,
        dontSpy: true): O & M;
    public objectMock<O, M extends Partial<O>>(objectClass: AbstractType<O>, mock: M):
        SpyObj<O> & M & O;
    public objectMock<O, M extends Partial<O>>(objectClass: undefined, mock: M): SpyObj<M>;

    public objectMock<O, M extends Partial<O>>(objectClass: AbstractType<O> | undefined, mock: M | any, dontSpy = false):
        O & M | SpyObj<O> & SpyObj<M> {
        return <O & M | SpyObj<O> & M>this.configurator.mock(undefined, mock, dontSpy, objectClass);
    }

    /**
     * Creates a mock object that satisfies the shape of a TypeScript interface I. This does not (and cannot)
     * replace I anywhere - interfaces have no runtime representation, so there is no prototype to reflect on
     * the way objectMock() reflects on a class. This means every member of I has to be supplied in mock - only
     * the methods you actually provide become spies, nothing can be auto-generated for the ones you omit.
     * Use this instead of objectMock(undefined, mock) purely to avoid casting the result to I & SpyObj<I> yourself.
     * @param mock an object implementing every member of I.
     * @param dontSpy optional parameter to prevent the default spy creation on the mock.
     * @returns your mock, typed as I & SpyObj<I>. Every method on it is a spy that calls through to the
     * implementation you supplied, like objectMock() does.
     */
    public interfaceMock<I>(mock: I, dontSpy = false): I & SpyObj<I> {
        return <I & SpyObj<I>>this.configurator.mock(undefined, mock, dontSpy, undefined);
    }

    /**
     * mocks a provider for a given token with a given mock. If wanted your mock can be extended by spies
     * from a given spySource class.
     * @param token token for provider provision
     * @param mock mock that will be registered for the token
     * @param dontSpy optional parameter to prevent the default spy creation on the mock.
     * @param spySource for each method in spySources prototype an additional spy will be created on the mock
     * @returns Your mocks methods will be overwritten with spies that call through to the mocks methods like spyOn method of your test framework.
     * In addition to that a spy will be added for each additional method that was found on the objectClass' prototype.
     */
    public providerMock<S, M extends Partial<S>>(token: ProviderToken<S>, mock: M, dontSpy: boolean = false, spySource?: AbstractType<Partial<S>>):
    S & M | SpyObj<S> & SpyObj<M> {
        return this.configurator.mock(token, mock, dontSpy, spySource) as  S & M | SpyObj<S> & SpyObj<M>;
    }


    /**
     * replaces a function that is provided with an angular provider token with a spy
     * @param token token that is used to provide a function
     * @param callback optional parameter to define default behavior for the mocked provider function
     * @returns spy on the mocked provider function
     */
    public providerFunctionMock<F extends Func = ()=>{}>(token: InjectionToken<F>, callback?: Partial<F> & Func): Spy<F> {
        const spy = createSpy('', callback as F) as Spy<F> & F;
        this.providerMock(token, spy, true);
        return spy;
    }

    /**
   *  mocks a service that has a "create" method.
   * @param factoryClass service that has a "create" method that you want to mock.
   * @param instances will be returned by the mock this method return when "create" is called.
   * The first call of mock.create() will return the first item in the instances-array and so on.
   * @returns a mock for the factory. mock.create will return the one of the given instances every time it is called
   */
    public factoryMock<I, F extends IFactory<I>, M>(factoryClass: AbstractType<F>, instances: Array<M & I>): SpyObj<F> {
        let index = -1;
        return <any>this.configurator.mock(factoryClass, <any>{
            create: (...args: any) => {
                index++;
                return instances[index];
            },
        }, false, factoryClass);
    }

    public serviceMock<S, M extends Partial<S>>(serviceClass: AbstractType<S>, mock: M,
        dontSpy: true): S & M;
    public serviceMock<S, M extends Partial<S>>(serviceClass: AbstractType<S>, mock: M):
        SpyObj<S> & SpyObj<M>;
    public serviceMock<S, M extends Partial<S>>(serviceClass: AbstractType<S>): SpyObj<S>;

    /**
     *  mocks a service with the given mock
     * @param serviceClass service that you want to mock
     * @param mock that should mock the service. All methods on the mock will become spies. For each method on serviceClass'
     * prototype another spy will be added to the mock.
     * @param dontSpy optional parameter to prevent the default spy creation on the mock.
     * @returns the mock after creating some spies on it (if not disabled)
     */
    public serviceMock<S, M extends Partial<S>>(serviceClass: AbstractType<S>, mock?: M, dontSpy?: boolean):
        S & M | SpyObj<S> & SpyObj<M> {
        return this.configurator.mock(serviceClass, mock, dontSpy, serviceClass);
    }


    /**
     *  return you the service or provider for a given token from the angular dependency injection.
     * This will trigger the TestBed configureTestingModule step. After this step you can not create any more mocks.
     * Make sure you create all your mocks before calling this method.
     * @param serviceClass service that you want to inject
     * @param token of the provider that you want to inject
     * @return whatever angular dependency injection finds for your token
     */
    public injection<S>(token: ProviderToken<S>): S {
        this.configurator.configureTestingModule();
        return TestBed.inject(token);
    }

    /**
    *
    * Subscribes to a given observable and spies on its states and emitted values.
    * @param observable
    * Observable you want to spy
    * @param name
    * Optional name that prefixes all spies that are created by the observer. This makes it easier to read the
    * test output if anything fails.
    * @returns
    * observer that can be used to make assertions in your test cases e.g.:
    * expect(observer.next).toHaveBeenCalledWith(expectedValue);
    * For more information check SpyObserver documentation
    */
    public observer<T>(observable: Observable<T>, name?: string): SpyObserver<T> {
        return observe(observable, name);
    }

    /**
    *
    * Subscribes to a given output and spies on its states and emitted values.
    * @param output
    * Output you want to spy
    * @param name
    * Optional name that prefixes all spies that are created by the observer. This makes it easier to read the
    * test output if anything fails.
    * @returns
    * outputObserver that can be used to make assertions in your test cases e.g.:
    * expect(outputObserver.next).toHaveBeenCalledWith(expectedValue);
    * For more information check SpyObserver documentation
    */
    public outputObserver<T>(output: OutputEmitterRef<T>, name?: string): SpyObserver<T>{
        return observe(outputToObservable(output), name);
    }
  
    /**
     *  
     * Can be used to run a callback in injection context. Like TestBed.runInInjectionContext().
     * Additionally this will trigger the TestBed configureTestingModule step. After this step you can not create any more mocks.
     * Make sure you create all your mocks before calling this method.
     * This method can be used to configure the testing module when used without 
     * @param callbackToBeRunInInjectionContext will be executed in injection context and its return value will be returned by run-method.
     * @returns what @param callbackToBeRunInInjectionContext would return
     */
    public run():void;
    public run<T>(callbackToBeRunInInjectionContext: ()=> T): T;
    public run<T = void>(callbackToBeRunInInjectionContext?: ()=> T): T {
        this.configurator.configureTestingModule();
        if(callbackToBeRunInInjectionContext){
            return TestBed.runInInjectionContext(()=> callbackToBeRunInInjectionContext());
        }
        return void(0) as T;
    }

}

result-matching ""

    No results matching ""