Skip to content

Commit

Permalink
fix(core): reset cached scope for components that were overridden usi…
Browse files Browse the repository at this point in the history
…ng TestBed (#52916)

Currently, when a component is overriden using `TestBed.overrideComponent`, Angular retains calculated scope for that component (a set of components and directives used within a component). This may cause stale information to be used in tests in some cases. This commit updates the logic to reset overridden component scope, so it gets re-computed during the next invocation.

Resolves #52817.

PR Close #52916
  • Loading branch information
AndrewKushnir authored and jessicajaniuk committed Nov 15, 2023
1 parent a523801 commit 5de7575
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
50 changes: 50 additions & 0 deletions packages/core/test/test_bed_spec.ts
Expand Up @@ -175,6 +175,56 @@ describe('TestBed with Standalone types', () => {
TestBed.resetTestingModule();
});

it('should override dependencies of standalone components', () => {
@Component({
selector: 'dep',
standalone: true,
template: 'main dep',
})
class MainDep {
}

@Component({
selector: 'dep',
standalone: true,
template: 'mock dep',
})
class MockDep {
}

@Component({
selector: 'app-root',
standalone: true,
imports: [MainDep],
template: '<dep />',
})
class AppComponent {
}

TestBed.configureTestingModule({imports: [AppComponent]});

let fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();

// No overrides defined, expecting main dependency to be used.
expect(fixture.nativeElement.innerHTML).toBe('<dep>main dep</dep>');

// Emulate an end of a test.
TestBed.resetTestingModule();

// Emulate the start of a next test, make sure previous overrides
// are not persisted across tests.
TestBed.configureTestingModule({imports: [AppComponent]});
TestBed.overrideComponent(AppComponent, {set: {imports: [MockDep]}});

fixture = TestBed.createComponent(AppComponent);
fixture.detectChanges();

// Main dependency was overridden, expect to see a mock.
expect(fixture.nativeElement.innerHTML).toBe('<dep>mock dep</dep>');
});


it('should override providers on standalone component itself', () => {
const A = new InjectionToken('A');

Expand Down
3 changes: 3 additions & 0 deletions packages/core/testing/src/test_bed_compiler.ts
Expand Up @@ -396,6 +396,9 @@ export class TestBedCompiler {
}

this.maybeStoreNgDef(NG_COMP_DEF, declaration);
if (USE_RUNTIME_DEPS_TRACKER_FOR_JIT) {
depsTracker.clearScopeCacheFor(declaration);
}
compileComponent(declaration, metadata);
});
this.pendingComponents.clear();
Expand Down

0 comments on commit 5de7575

Please sign in to comment.