Angular

Angular logs the “not a known element” error as a warning

In Angular 9 and 10 we can notice that the “my-element is not a known element” error is missing when our tests don’t have all required stubs. Make sure to check debug messages when running tests and add all absent stubs. Otherwise, you will have to update your test suite when the Angular team fixes this bug.

I noticed the issue that I describe here when working with the following Angular version:

$ ng --version

Angular CLI: 10.1.4
Node: 12.19.0
OS: linux x64

Angular: 10.1.4
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router
Ivy Workspace: Yes

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1001.4
@angular-devkit/build-angular   0.1001.4
@angular-devkit/core            10.1.4
@angular-devkit/schematics      10.1.4
@schematics/angular             10.1.4
@schematics/update              0.1001.4
rxjs                            6.5.4
typescript                      3.9.7

Consequences of missing error when the nested element is not known

It seems that since version 9 Angular handles unknown elements in unit tests differently than the previous releases. If we forget to stub an element that we used inside a component under test, the test will pass. Furthermore, the message about an unknown element will be displayed only in the debug window.

The guest-layout.component.spec file is an example test file:

// src/main/angular/src/app/layout/guest/guest-layout/guest-layout.component.spec.ts
…
@Component({selector: 'app-guest-nav', template: ''})
class GuestNavComponent {}

@Component({selector: 'app-page-content', template: ''})
class PageContentComponent { }

@Component({selector: 'app-guest-footer', template: ''})
class GuestFooterComponent {}

describe('GuestLayoutComponent', () => {
  …
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        GuestLayoutComponent,
        GuestNavComponent,
        PageContentComponent,
        GuestFooterComponent
       ]
    })
    .compileComponents();
  }));
…

As we can see, I created stubs for the GuestNavComponent, PageContentComponent and GuestFooterComponent and declared them in the TestBed configuration. If I run the $ ng test command now, all tests pass.

If I was to remove the PageContentComponent stub declaration from the test and run it again, the outcome would still be positive. We won’t see any errors in the test result. Instead, we have to debug to find the app-page-content' is not a known element – the error is missing from the summary, as we can see on the screenshot below:

Consequently, you don’t know for sure whether you stubbed all nested components or not until you check debug messages.

There are multiple issues on GitHub that address this problem. One of them has been recently labeled as High priority issue that should be resolved as soon as possible. However, for now, we have to manually verify debug messages to find missing nested component declarations. If you commit code without fixing the warnings, you risk a lot of broken tests once you update your project to the Angular version that reintroduces the error.

How to disable “not a known element error” permanently

On the other hand, if you added the NO_ERRORS_SCHEMA to the TestBed.schemas, Angular compiler already ignores unrecognized elements and attributes. This means that you don’t have to stub elements. In this case, you won’t get any hints if you forget to declare a nested component even after the Angular team fixes the bug. Nevertheless, don’t forget about consequences of this approach:

The NO_ERRORS_SCHEMA also prevents the compiler from telling you about the missing components and attributes that you omitted inadvertently or misspelled. You could waste hours chasing phantom bugs that the compiler would have caught in an instant.

https://angular.io/guide/testing-components-scenarios#use-both-techniques-together

More on testing components with nested elements in Angular

Photo by Ba Phi from Pexels

little_pinecone

Share
Published by
little_pinecone

Recent Posts

Simplify the management of user roles in Spring Boot

Spring Security allows us to use role-based control to restrict access to API resources. However,…

3 years ago

Create a custom annotation to configure Spring Boot tests

A custom annotation in Spring Boot tests is an easy and flexible way to provide…

3 years ago

Keycloak with Spring Boot #4 – Simple guide for roles and authorities

Delegating user management to Keycloak allows us to better focus on meeting the business needs…

3 years ago

Keycloak with Spring Boot #3 – How to authorize requests in Swagger UI

Swagger offers various methods to authorize requests to our Keycloak secured API. I'll show you…

3 years ago

Keycloak with Spring Boot #2 – Spring Security instead of Keycloak in tests

Configuring our Spring Boot API to use Keycloak as an authentication and authorization server can…

3 years ago

Keycloak with Spring Boot #1 – Configure Spring Security with Keycloak

Keycloak provides simple integration with Spring applications. As a result, we can easily configure our…

3 years ago