@@ -78,7 +78,14 @@ export class TestBedCompiler {
7878
7979 private resolvers : Resolvers = initResolvers ( ) ;
8080
81- private componentToModuleScope = new Map < Type < any > , Type < any > | TestingModuleOverride > ( ) ;
81+ // Map of component type to an NgModule that declares it.
82+ //
83+ // There are a couple special cases:
84+ // - for standalone components, the module scope value is `null`
85+ // - when a component is declared in `TestBed.configureTestingModule()` call or
86+ // a component's template is overridden via `TestBed.overrideTemplateUsingTestingModule()`.
87+ // we use a special value from the `TestingModuleOverride` enum.
88+ private componentToModuleScope = new Map < Type < any > , Type < any > | TestingModuleOverride | null > ( ) ;
8289
8390 // Map that keeps initial version of component/directive/pipe defs in case
8491 // we compile a Type again, thus overriding respective static fields. This is
@@ -457,15 +464,20 @@ export class TestBedCompiler {
457464 } ;
458465
459466 this . componentToModuleScope . forEach ( ( moduleType , componentType ) => {
460- const moduleScope = getScopeOfModule ( moduleType ) ;
461- this . storeFieldOfDefOnType ( componentType , NG_COMP_DEF , 'directiveDefs' ) ;
462- this . storeFieldOfDefOnType ( componentType , NG_COMP_DEF , 'pipeDefs' ) ;
467+ if ( moduleType !== null ) {
468+ const moduleScope = getScopeOfModule ( moduleType ) ;
469+ this . storeFieldOfDefOnType ( componentType , NG_COMP_DEF , 'directiveDefs' ) ;
470+ this . storeFieldOfDefOnType ( componentType , NG_COMP_DEF , 'pipeDefs' ) ;
471+ patchComponentDefWithScope ( getComponentDef ( componentType ) ! , moduleScope ) ;
472+ }
463473 // `tView` that is stored on component def contains information about directives and pipes
464474 // that are in the scope of this component. Patching component scope will cause `tView` to be
465475 // changed. Store original `tView` before patching scope, so the `tView` (including scope
466476 // information) is restored back to its previous/original state before running next test.
477+ // Resetting `tView` is also needed for cases when we apply provider overrides and those
478+ // providers are defined on component's level, in which case they may end up included into
479+ // `tView.blueprint`.
467480 this . storeFieldOfDefOnType ( componentType , NG_COMP_DEF , 'tView' ) ;
468- patchComponentDefWithScope ( ( componentType as any ) . ɵcmp , moduleScope ) ;
469481 } ) ;
470482
471483 this . componentToModuleScope . clear ( ) ;
@@ -604,10 +616,7 @@ export class TestBedCompiler {
604616 // real module, which was imported. This pattern is understood to mean that the component
605617 // should use its original scope, but that the testing module should also contain the
606618 // component in its scope.
607- //
608- // Note: standalone components have no associated NgModule, so the `moduleType` can be `null`.
609- if ( moduleType !== null &&
610- ( ! this . componentToModuleScope . has ( type ) ||
619+ if ( ( ! this . componentToModuleScope . has ( type ) ||
611620 this . componentToModuleScope . get ( type ) === TestingModuleOverride . DECLARATION ) ) {
612621 this . componentToModuleScope . set ( type , moduleType ) ;
613622 }
0 commit comments