How to fix "Error: Expected to be running in 'ProxyZone', but it was not found." in mocha testing?

22.8k Views Asked by At

I am trying to test my Tour of Heroes Angular application using mocha, chai & webpack. I have followed this post & also with the help of this guide, have gone through the setup and got the build errors fixed and tests up and running.

But, my tests fails except for the test case where I don't use the async() in the beforeEach hook.

Passing Test

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [HeroService, MessageService]
    });
    httpTestingController = TestBed.get(HttpTestingController);

    let mockHeroes = [...mockData];
    let mockHero = mockHeroes[0];
    // let mockId = mockHero.id;

    heroService = TestBed.get(HeroService);
  });

  afterEach(() => {
    httpTestingController.verify();
  });

  it('is created', () => {
    expect(heroService).to.exist;
  });

Failing Test

//imports
import { async, ComponentFixture, TestBed } from '@angular/core/testing';

import { DashboardComponent } from './dashboard.component';
import { HeroSearchComponent } from '../hero-search/hero-search.component';

import { RouterTestingModule } from '@angular/router/testing';
import { HeroService } from '../hero.service';
import { expect } from 'chai';

...

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [DashboardComponent, HeroSearchComponent],
      imports: [RouterTestingModule.withRoutes([])],
      providers: [{ provide: HeroService, useValue: heroService }]
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(DashboardComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should be created', () => {
    expect(component).to.exist;
  });

Error Stack Trace

  1. DashboardComponent
  "before each" hook for "should be created":
Error: Expected to be running in 'ProxyZone', but it was not found.
 at Function.ProxyZoneSpec.assertPresent (node_modules\zone.js\dist\proxy.js:42:19)
 at runInTestZone (node_modules\zone.js\dist\async-test.js:202:23)
 at D:\Practice\Tour-Of-Heroes\node_modules\zone.js\dist\async-test.js:185:17
 at new ZoneAwarePromise (node_modules\zone.js\dist\zone-node.js:910:29)
 at Context.<anonymous> (node_modules\zone.js\dist\async-test.js:184:20)

I have tried Angular 5 Testing: Expected to be running in 'ProxyZone', but it was not found as I thought this was some error with zone.js using mocha, but without success.

Also, I have tried following Mocha Documentation for asynchronous testing, but as a beginner, it was somewhat hard for me.

I have tried googling and even in Stack Overflow, but there are only a limited amount of posts regarding Angular testing with mocha. Any help getting through this is appreciated.

7

There are 7 best solutions below

1
Francesco Borzi On BEST ANSWER

I had the same issue when accidentally using fakeAsync in a describe function.

Removed it solved the issue for me.

1
Alexei Eleusis Díaz Vera On

I had the same issue and removing async from beforeEach (and it) solved the problem. The error message is not helpful at all, but I guess is not easy from where it is generated to detect what the root cause is.

0
Naveen Motwani - AIS On

Here is the answer to this question.

Angular 5 Testing: Expected to be running in 'ProxyZone', but it was not found

Basically this exception is coming because of the incorrect position of an async keyword. Remove the async from beforeEach and add it on "it"

it('should be created', fakeAsync(() => {
    expect(component).to.exist;
  });
1
Jeff On

I see a few issues here.

You have 2 beforeEach. You should only have 1. If you have async on your block of test code, then you need to call await on a function, and/or use flush or tick to progress time. I usually use fakeAsync for observables, and async/await for real async methods.

For this specific example, you shouldn't need the async at all.

1
Yevhenii Bahmutskyi On

2021

Adding the line below as first import to the spec file fixed this problem for me:

import 'zone.js/dist/zone-testing';
0
jonathan Heindl On

with angular 14 we added imports (to fix our jest setup) to

  require('zone.js');
  require('zone.js/testing');

in our jest setupFilesAfterEnv file however when running with ng test those imports are alreaddy done by angular resulting in duplicate imports and conflicts resulting in the above error

the solutions then was to wrap the imports in a condition:

if (!('Zone' in global)){
  require('zone.js');
  require('zone.js/testing');
}
0
fservantdev On

In my case, the solution was to add "target": "ES2016" in the tsconfig.spec.json file.

Indeed, after migrating my app to Angular 15, I set "target": "ES2022" in the main tsconfig.json (as suggested here).
But it raises a well-known issue in the tests using async/await syntax.

Credits to: https://github.com/nrwl/nx/issues/15577#issuecomment-1465737796