How to Unit Test Angular’s Standalone Components

Angular 14 added a long-awaited feature: standalone components. As the name implies, you can build these components independently without adding them to a module’s declarations. However, to unit test these components, we need to make some changes to the typical boilerplate we use when testing components. Particularly with the way we configure the dependency injection system to be able to provide mocks to our testing environment.

Creating a Basic Standalone Component

Just like regular components, we can use the Angular CLI to generate a standalone component along with all the typical boilerplate files and code needed.

ng generate component <your-component-name> --standalone

Or with the shorthand:

ng g c <your-component-name> --standalone

Depending on how your project is configured, you should now have the typescript file, the HTML file, the SCSS file, and the spec file all available in your project. If we look at the typescript file for our component, you will notice some slight differences in how the @Component decorator is configured.

The standalone: true property is self-explanatory and expected. But the other interesting line is imports: [CommonModule]. This imports field is where we can bring in any other standalone components, pipes, or modules that our component needs. In this case, the Angular CLI has already imported the CommonModule for us, home to things like *ngFor and *ngIf.

If we go into the app.component.html file and try to use our standalone component, we will get an error when running our app that says our component is not a known element. Standalone components may not need to be added to any module’s declarations, but they do need to be imported anywhere they will be used. This is easy to fix. We can go into the AppModule and add our component to the imports list:

 

Now, your application should build successfully using your new standalone component.

Mocking Dependencies

Unfortunately, mocking dependencies for standalone components requires a slightly different setup than traditional components, but it is still fairly straightforward.

Let’s say that our standalone component depends on a service in our project, ExampleService. To mock this dependency in our test, we must use the overrideComponent method on the TestBed. This method will allow us to remove the default providers and provide our mocks. Our test setup should now look something like this:

Simplify with Standalone Components

Standalone components are a great way to simplify an Angular application. I am trying to understand why the traditional way of mocking dependencies for components does not work for their standalone counterparts. However, I am confident there’s a technical reason the Angular team had to implement it this way. Hopefully, in the future, they can coalesce these two methods into a unified strategy.

Conversation

Join the conversation

Your email address will not be published. Required fields are marked *