import { ComponentFixture , TestBed } from '@angular/core/testing' ; import { BrowserDynamicTestingModule , platformBrowserDynamicTesting , } from '@angular/platform-browser-dynamic/testing' ; const testBed = TestBed . initTestEnvironment ( [ BrowserDynamicTestingModule ] , platformBrowserDynamicTesting ( ) ) ; patchTestBedToDestroyFixturesAfterEveryTest ( testBed ) ; ( window as any ) . module = { } ; ( window as any ) . isNode = false ; ( window as any ) . isBrowser = true ; ( window as any ) . global = window ; /**
 * Monkey-patches TestBed.resetTestingModule such that any errors that occur during component
 * destruction are thrown instead of silently logged. Also runs TestBed.resetTestingModule after
 * each unit test.
 *
 * Without this patch, the combination of two behaviors is problematic for Angular MDC:
 * - TestBed.resetTestingModule catches errors thrown on fixture destruction and logs them without
 *     the errors ever being thrown. This means that any component errors that occur in ngOnDestroy
 *     can encounter errors silently and still pass unit tests.
 * - TestBed.resetTestingModule is only called *before* a test is run, meaning that even *if* the
 *    aforementioned errors were thrown, they would be reported for the wrong test (the test that's
 *    about to start, not the test that just finished).
 */ function patchTestBedToDestroyFixturesAfterEveryTest ( testBedInstance ) { const _resetTestingModule = testBedInstance . resetTestingModule ; testBedInstance . resetTestingModule = function ( this ) { try { this . _activeFixtures . forEach ( ( fixture ) => fixture . destroy ( ) ) ; } finally { this . _activeFixtures = [ ] ; _resetTestingModule . call ( this ) ; } } ; afterEach ( ( ) => testBedInstance . resetTestingModule ( ) ) ; }