Streamlining Angular Testbed Configuration with Synchronous Hooks

When generating components via Angular's schematics, the resulting test setup hook often includes unnecessary asynchronous code.

Here's the test setup that Angular's component schematic produces:

beforeEach(async () => {
  await TestBed.configureTestingModule({
    declarations: [MyComponent],
  }).compileComponents();
});
Enter fullscreen mode Exit fullscreen mode
Angular testbed setup generated by the component schematic.

Alternatively, you might be using the waitForAsync test wrapper (previously called async), as shown below:

beforeEach(waitForAsync(() => {
  TestBed.configureTestingModule({
    declarations: [MyComponent],
  }).compileComponents();
}));
Enter fullscreen mode Exit fullscreen mode
Angular testbed setup using waitForAsync.

The key insight is this: calling the static TestBed.compileComponents method is required only when tests are executed outside the Angular CLI — a scenario that's quite uncommon.

Since the Angular CLI compiles both the application and the test files before running the tests, there's no need for asynchronous setup of declarables.

We can trim the standard test setup by removing async-await, waitForAsync, and the TestBed.compileComponents call entirely, as demonstrated here:

beforeEach(() => {
  TestBed.configureTestingModule({
    declarations: [MyComponent],
  });
});
Enter fullscreen mode Exit fullscreen mode
Simplified Angular testbed setup.

The following observations hold for standard Angular testbed configuration when testing any type of Angular declarable:

  • Avoid async-await
  • Avoid waitForAsync (formerly named async)
  • Avoid invoking TestBed.compileComponents

There may be valid reasons to introduce asynchrony into test setup, but compiling and linking declarables isn't one of them.

Enjoy reducing boilerplate in your Angular tests 🌞