Angular 6 Unit Tests: An error was thrown in afterAll\nReferenceError: Can't find variable: $ thrown

Oisin picture Oisin · Jul 26, 2018 · Viewed 51.2k times · Source

When running my unit tests, from time to time, even if they pass, at the end of all the tests running, I will get the following error.

On my Jenkins CI build running PhantomJS:

.PhantomJS 2.1.1 (Linux 0.0.0) ERROR
  {
    "message": "An error was thrown in afterAll\nReferenceError: Can't find variable: $ thrown",
    "str": "An error was thrown in afterAll\nReferenceError: Can't find variable: $ thrown"
  }

Or on Chrome:

Chrome 67.0.3396 (Windows 7 0.0.0) ERROR
  {
    "message": "An error was thrown in afterAll\n[object ErrorEvent] thrown",
    "str": "An error was thrown in afterAll\n[object ErrorEvent] thrown"
  }

I also have really unreliable tests, without changing anything some times they would succeed and other times the same tests would fail, so I knew something weird was going on.

Answer

Oisin picture Oisin · Jul 26, 2018

My issue was that I had a race condition in my tests due to a very stupid way of setting up my tests, but I wanted to document it here anyways because I struggled to find the answer to my issue on the internet.

What I had somehow done was to declare two beforeEach functions to setup my test, and one of the two was asynchronous, so I had a race condition where sometimes they ran out of order and failed.

Here is how my test looked:

beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [ HomeComponent ]
    })
    .compileComponents();
  }));

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

So to resolve this I put all the setup into one, synchronous beforeEach.

  beforeEach(() => {
    TestBed.configureTestingModule({
      declarations: [HomeComponent]
    }).compileComponents();
    fixture = TestBed.createComponent(HomeComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

I wasted too much time trying to figure this out, so I'm putting it here to save someone else.