从 Angular 7 升级到 Angular 8 后,我的管道测试停止工作:TypeError: undefined is not iterable

Posted

技术标签:

【中文标题】从 Angular 7 升级到 Angular 8 后,我的管道测试停止工作:TypeError: undefined is not iterable【英文标题】:After upgrading from Angular 7 to Angular 8 my pipe test stopped to work: TypeError: undefined is not iterable 【发布时间】:2020-01-31 14:25:36 【问题描述】:

我正在使用 Jest 对我的 Angular8 组件进行单元测试。我从测试通过的 A7 执行升级。 现在我得到一个错误:

FAIL src/app/core/pipes/client/client.pipe.spec.ts (21.395s)
  ● ClientPipe › should format person

    TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator))

      10 | export class ClientPipe implements PipeTransform 
      11 |
    > 12 |   constructor(
         |               ^
      13 |     private readonly personPipe: PersonPipe,
      14 |     private readonly organizationPipe: OrganizationPipe) 
      15 |

      at Object.<anonymous>.__read (src/app/core/pipes/client/client.pipe.ts:12:46)
      at Object.<anonymous>.__spread (src/app/core/pipes/client/client.pipe.ts:28:72)

这是管道的sn-p:

@Pipe(
  name: 'client'
)
export class ClientPipe implements PipeTransform 

  constructor(
    private readonly personPipe: PersonPipe,
    private readonly organizationPipe: OrganizationPipe) 

  transform(client: Client | any, args?: any): any 
    if (client.person) 
      return this.personPipe.transform(client.person, ...args);
     else 
      return this.organizationPipe.transform(client.organization, ...args);
    

    return ' — ';
  

错误实际上来自以下行:

return this.personPipe.transform(client.person, ...args)

其中使用了 spread 运算符。 tsconfig.spec.json 扩展了 tsconfig.json,其中 target 设置为 es5,所以我不明白为什么 Jest 会失败。

在浏览器中我遇到了类似的错误(错误:找到不可调用的@@iterator)。它有助于将 tsconfig.json targetes2015 更改为 es5。但我对 Jest 配置束手无策。

tsconfig.spec.ts:


  "extends": "../tsconfig.json",
  "compilerOptions": 
    "outDir": "../out-tsc/spec",
    "types": ["jest"]
  ,
 "files": [
    "polyfills.ts"
  ],
  "include": [
    "**/*.spec.ts",
    "**/*.d.ts"
  ]

tsconfig.json:


  "compileOnSave": false,
  "compilerOptions": 
    "downlevelIteration": true,
    "module": "esnext",
    "outDir": "./dist/out-tsc",
    "baseUrl": "./src",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es5",
    "types": ["jest"],
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2017",
      "dom"
    ]
  

带有 Jest 配置的 package.json:


  "name": "Test",
  "version": "0.0.0",
  "license": "MIT",
  "scripts": 
    "ng": "ng",
    "serve": "node --max_old_space_size=8192 node_modules/@angular/cli/bin/ng serve",
    "test": "jest",
    "test-ci": "jest",
    "lint": "ng lint",
    "lint-ci": "ng lint --format tslint-teamcity-reporter",
    "format:check": "prettier --config ./.prettierrc --list-different \"src/app,environments,assets/**/*.ts,.js,.json,.css,.scss\"",
    "e2e": "ng e2e",
    "test:debug": "node --inspect node_modules/jest/bin/jest --watch --runInBand -t 'ClientPipe'"
  ,
  "private": true,
  "dependencies": 
    "@angular/animations": "8.2.6",
    "@angular/cdk": "8.2.0",
    "@angular/common": "8.2.6",
    "@angular/compiler": "8.2.6",
    "@angular/core": "8.2.6",
    "@angular/flex-layout": "8.0.0-beta.27",
    "@angular/forms": "8.2.6",
    "@angular/material": "8.2.0",
    "@angular/material-moment-adapter": "8.2.0",
    "@angular/platform-browser": "8.2.6",
    "@angular/platform-browser-dynamic": "8.2.6",
    "@angular/router": "8.2.6",
    "@ngrx/effects": "8.3.0",
    "@ngrx/router-store": "8.3.0",
    "@ngrx/store": "8.3.0",
    "@ngrx/store-devtools": "8.3.0",
    "@ngx-translate/core": "11.0.1",
    "@ngx-translate/http-loader": "4.0.0",
    "core-js": "3.2.1",
    "error-stack-parser": "2.0.3",
    "hammerjs": "2.0.8",
    "lodash": "4.17.15",
    "moment": "2.24.0",
    "ngx-take-until-destroy": "5.4.0",
    "rxjs": "6.5.3",
    "tslib": "^1.10.0",
    "ts-md5": "1.2.4",
    "web-animations-js": "2.3.2",
    "zone.js": "~0.9.1"
  ,
  "devDependencies": 
    "@angular-builders/jest": "7.4.2",
    "@angular-devkit/build-angular": "0.803.6",
    "@angular/cli": "8.3.4",
    "@angular/compiler-cli": "8.2.6",
    "@angular/language-service": "8.2.6",
    "@ngrx/schematics": "8.3.0",
    "@types/jest": "23.3.14",
    "@types/lodash": "4.14.125",
    "@types/node": "8.10.36",
    "browser-sync": "2.26.7",
    "codelyzer": "5.1.2",
    "istanbul-reports": "2.2.5",
    "jest": "24.8.0",
    "jest-cli": "24.1.0",
    "jasmine-marbles": "0.4.1",
    "jest-preset-angular": "7.1.1",
    "jest-sonar-reporter": "2.0.0",
    "jest-teamcity-reporter": "0.9.0",
    "json-loader": "0.5.7",
    "ngx-wallaby-jest": "0.0.2",
    "prettier": "1.18.2",
    "protractor": "5.4.1",
    "rxjs-tslint-rules": "4.25.0",
    "ts-node": "7.0.1",
    "tslint": "5.16.0",
    "tslint-eslint-rules": "5.4.0",
    "tslint-microsoft-contrib": "6.1.1",
    "tslint-teamcity-reporter": "3.2.2",
    "typescript": "3.5.3",
    "wallaby-webpack": "3.9.15"
  ,
  "jest": 
    "preset": "jest-preset-angular",
    "globals": 
      "ts-jest": 
        "tsConfig": "<rootDir>/src/tsconfig.spec.json",
        "stringifyContentPathRegex": "\\.html$",
        "astTransformers": [
          "jest-preset-angular/InlineHtmlStripStylesTransformer"
        ],
        "diagnostics": 
          "warnOnly": true
        
      
    ,
    "moduleNameMapper": 
      "@core/(.*)": "<rootDir>/src/app/core/$1",
      "@shared/(.*)": "<rootDir>/src/app/shared/$1",
      "@views/(.*)": "<rootDir>/src/app/views/$1",
      "@app/(.*)": "<rootDir>/src/app/$1",
      "environments/(.*)": "<rootDir>/src/environments/$1"
    ,
    "setupFilesAfterEnv": [
      "<rootDir>/src/setupJest.ts"
    ],
    "testResultsProcessor": "jest-teamcity-reporter"
  

编辑 1 - 控制台中有额外的警告,可能是也可能不是一些线索

ts-jest[jest-transformer] (WARN) Got a `.js` file to compile while `allowJs` option is not set to `true` (file: C:\xxxx\node_modules\@ngrx\effects\bundles\effects.umd.js). To fix this:
- if you want TypeScript to process JS files, set `allowJs` to `true` in your TypeScript config (usually tsconfig.json)
- if you do not want TypeScript to process your `.js` files, in your Jest config change the `transform` key which value is `ts-jest`   so that it does not match `.js` files anymore
ts-jest[jest-transformer] (WARN) Got a `.js` file to compile while `allowJs` option is not set to `true` (file: C:\xxxx\node_modules\@ngrx\store\bundles\store.umd.js). To fix this:
- if you want TypeScript to process JS files, set `allowJs` to `true` in your TypeScript config (usually tsconfig.json)
- if you do not want TypeScript to process your `.js` files, in your Jest config change the `transform` key which value is `ts-jest`   so that it does not match `.js` files anymore

【问题讨论】:

你能添加你的包json吗?也许 ng update 没有更新所有依赖项,例如@angular-devkit/build-angular... @zerocewl 完成,请展开最后一个 sn-p。 【参考方案1】:

尝试更新 "@angular-builders/jest": "7.4.2" 它看起来已经过时了

@angular-builders/jest 目前是 v 8.2.0。

例如:

npm install @angular-builders/jest@8.2.0 --dev

或使用纱线

yarn add @angular-builders/jest@8.2.0 --dev

【讨论】:

尝试将"emitDecoratorMetadata": true, 添加到 tsconfig.spec.json 中的 compilerOptions。查看更改github.com/thymikee/jest-preset-angular/pull/311/commits/… 或者尝试比较 Angular 8 jest-preset-angular 更改后的Example 项目【参考方案2】:

错误出现在扩展运算符中 - undefined 上的 spreaderror

这里也有解释:javascript ES6 spread operator on undefined

对我来说奇怪的是在 Angular7 中工作 - 如果没有向 Angular 管道提供参数,它可能提供了默认的空值而不是 undefined

【讨论】:

以上是关于从 Angular 7 升级到 Angular 8 后,我的管道测试停止工作:TypeError: undefined is not iterable的主要内容,如果未能解决你的问题,请参考以下文章

从 Angular 4 升级到 7 导致问题

从 8 升级到 9 后无法构建 Angular 项目

通过5个简单步骤升级到Angular 7

升级到 9.0 和 angular 7 后修复 angular-redux/store

为啥升级到 Angular 7 Ecma6 不起作用?

从 Angular 5 升级到 Angular 6,Bootstrap 按钮样式没有间距