Search code examples
angularangular9angular-i18ntestbed

Angular 9 i18n migration - failing tests


I am upgrading from Angular 8.0 to Angular 9.1.1. With a little bit of work, everything builds and runs fine. I ran into the localization issue https://angular.io/guide/migration-localize and followed these instructions - this allowed my project to build and run! However, I am still getting this issue when I run tests (karma/jasmine)

I used the CLI to upgrade my project. I can't seem to find any other required steps to migrate localization.

I am using TestBed for the unit tests and they fail when calling TestBed.createComponent, throwing the error:

Error: It looks like your application or one of its dependencies is using i18n.
        Angular 9 introduced a global `$localize()` function that needs to be loaded.
        Please run `ng add @angular/localize` from the Angular CLI.
        (For non-CLI projects, add `import '@angular/localize/init';` to your `polyfills.ts` file.
        For server-side rendering applications add the import to your `main.server.ts` file.)

An example piece of HTML from a failing tests component template is:

<span i18n>
    label
</span>

Simply removing i18n allows the tests to run and pass - but this is not a runtime error when the app runs. Any clues on where to look next or what else might be involved here?

The top of my polypill.js

/***************************************************************************************************
 * Load `$localize` onto the global scope - used if i18n tags appear in Angular templates.
 */
import '@angular/localize/init';

/**
 * This file includes polyfills needed by Angular and is loaded before the app.
 * You can add your own extra polyfills to this file.
 *
...

my package.json dependencies

  "dependencies": {
    "@angular/animations": "^9.1.1",
    "@angular/common": "^9.1.1",
    "@angular/compiler": "^9.1.1",
    "@angular/core": "^9.1.1",
    "@angular/forms": "^9.1.1",
    "@angular/localize": "^9.1.1",
    "@angular/platform-browser": "^9.1.1",
    "@angular/platform-browser-dynamic": "^9.1.1",
    "@angular/router": "^9.1.1",
    "core-js": "^3.0.0",
    "moment": "^2.24.0",
    "prismjs": "^1.16.0",
    "rxjs": "~6.5.5",
    "tslib": "^1.10.0",
    "zone.js": "~0.10.2"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.901.1",
    "@angular-devkit/build-ng-packagr": "~0.901.1",
    "@angular/cli": "^9.1.1",
    "@angular/compiler-cli": "^9.1.1",
    "@angular/language-service": "^9.1.1",
    "@types/jasmine": "^3.3.13",
    "@types/jasminewd2": "^2.0.6",
    "@types/node": "^12.11.1",
    "codelyzer": "^5.1.2",
    "jasmine-core": "~3.4.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "^4.2.0",
    "karma-chrome-launcher": "^2.2.0",
    "karma-coverage-istanbul-reporter": "^2.1.0",
    "karma-jasmine": "^2.0.0",
    "karma-jasmine-html-reporter": "^1.4.2",
    "ng-packagr": "^9.0.0",
    "ts-node": "^8.2.0",
    "tslint": "^5.18.0",
    "typescript": "~3.8.3"
  }

Solution

  • The polyfill was not included in the test, so I had to add the polyfil configuration option in angular.json

      "builder": "@angular-devkit/build-angular:karma",
              "options": {
                "polyfills": "polyfills.ts",
                ...
              }
            },
    

    and make sure it was included in the tsconfig.spec.json

    "include": [
        "**/*.spec.ts",
        "**/*.d.ts",
        "polyfills.ts"
      ]