Angular 2单元测试:无法找到名称为“describe”的内容。

235

我正在跟随angular.io上的这篇教程

正如他们所说,我已经创建了hero.spec.ts文件来创建单元测试:

import { Hero } from './hero';
describe('Hero', () => {
  it('has name', () => {
    let hero: Hero = {id: 1, name: 'Super Cat'};
    expect(hero.name).toEqual('Super Cat');
  });
  it('has id', () => {
    let hero: Hero = {id: 1, name: 'Super Cat'};
    expect(hero.id).toEqual(1);
  });
});

单元测试非常有效,但问题是:我看到一些错误,这些错误在教程中提到:

我们的编辑器和编译器可能会抱怨它们不知道 itexpect 是什么,因为它们缺少描述 Jasmine 的类型文件。目前我们可以忽略那些烦人的投诉,因为它们是无害的。

他们实际上忽略了它。 尽管这些错误是无害的,但当我收到大量这些错误时,在输出控制台中并不好看。

以下是我得到的示例:

找不到名称“describe”。

找不到名称“it”。

找不到名称“expect”。

我该怎么办才能解决它?


1
你可以在 Github 上点赞来修复这个 bug:https://github.com/TypeStrong/atom-typescript/issues/1125 - Lucas Cimon
17个回答

431
我希望您已经安装了 -
npm install --save-dev @types/jasmine

然后在hero.spec.ts文件的顶部添加以下导入语句 -

import 'jasmine';

它应该解决这个问题。


3
根据所需的Typescript版本,你可能需要安装早期版本。例如,对于我当前使用的ionic v2.2.1和typescript v2.0.9,我需要安装@types/jasmine@2.5.41。否则,你可能会看到这些编译错误 - Tony O'Hagan
19
你可以导入该模块以获得其副作用:import 'jasmine'; - cmolina
8
import {} from 'jasmine'; 的实际作用是导入来自 jasmine 模块的命名导出项,而 import 'jasmine' 则仅导入整个 jasmine 模块。两者并不相同。 - TetraDev
2
在 Angular 6.0.3 中:我刚刚导入了“从 jasmine 导入 {}”并且它又可以工作了。 - Eduardo Cordeiro
2
@aesede 你用的是哪个版本的PS?我刚刚执行了这个命令,没有加任何引号,一切都很顺利。 - Konrad Viltersten
显示剩余6条评论

180

使用 Typescript@2.0 或更高版本,您可以通过以下方式安装类型:

npm install -D @types/jasmine

然后,在tsconfig.json中使用types选项自动导入类型:

"types": ["jasmine"],

这个解决方案不需要在每个规范文件中使用import {} from 'jasmine';


10
根据TypeScript文档中的tsconfig.json(此时为v2.1),不再需要添加“types”:[“jasmine”]行。 “默认情况下,您的编译中包括所有可见的“@types”包。在任何封闭文件夹的node_modules/@types中的包都被视为可见;具体来说,这意味着./node_modules/@types/,../node_modules/@types/,../../node_modules/@types/等文件夹中的包。” - bholben
12
我知道,但出于某种原因nodejasmine类型无法被检测到。至少在我的Typescript@2.1.5环境中是这样,我无法使用它们。 - Jiayi Hu
2
这个解决方案对我不起作用 :(,抱歉。我在 ang-app/e2e/tsconfig.json 中使用它。_我在每个 json 级别都尝试了一遍_。你能否添加更多细节? - Sergii
在使用webpack时,这种方法行不通 - 在这种情况下,实际的库需要被提供 - import {} from 'jasmine' 会将库推送通过。 - Bogdan
这个解决方案对我很有效。但是我不得不将它添加到基本的 tsconfig.json 文件中。我的项目是使用 angular/cli 创建的,因此它带有几个不同的 tsconfig 文件,其中一个是 tsconfig.spec.json,它已经有了 "types": [ "jasmine" ]。但似乎它没有被读取。相反,我不得不将其添加到基本的 tsconfig 文件中。 - starcorn
显示剩余3条评论

28
npm install @types/jasmine

如评论中提到的,不再需要"types": ["jasmine"],所有@types包都会自动包含在编译中(从v2.1开始,我想是这样)。

我认为最简单的解决方案是在您的tsconfig.json中排除测试文件,例如:

"exclude": [
    "node_modules",
    "**/*.spec.ts"
]

这对我很有效。

在官方的tsconfig文档中可以找到更多信息。


4
注意:新的Angular项目有src/tsconfig.app.jsonsrc/tsconfig.spec.jsontsconfig.json。所提到的"exclude"部分是第一个文件中的一部分。"types": ["jasmine"]是第二个文件中的一部分。 - Martin Schneider
2
请注意,使用VS Code时,您将失去在规范文件中查找引用的功能,因为它们不会被视为项目的一部分。 - mleu
@mleu 我也遇到了同样的问题。你是如何解决这个问题的?每次编写测试用例时,我都必须从 exclude 块中删除规范文件模式。 - Shishir Anshuman
@ShishirAnshuman:我没有找到解决方案,只能忍受这个限制,直到项目结束。 - mleu
1
@mleu 哦,没问题。在我的项目中,我从tsconfig的exclude块中删除了规范文件模式。然后我创建了一个新的tsconfig.build.json文件,并将规范文件模式添加到exclude块中。现在,在我的webpack.config中的ts-loader选项中,我正在使用tsconfig.build.json。通过这些配置,测试文件中的模块被解析,而在创建构建或启动服务器时,测试文件被排除在外。 - Shishir Anshuman
使用“include”包含的文件可以使用“exclude”属性进行过滤。但是,使用“files”属性明确包含的文件始终会被包含,而不考虑“exclude”。当未指定时,“exclude”属性默认排除node_modules、bower_components、jspm_packages和<outDir>目录。您应该在tsconfig.app.json文件中添加"exclude": ["**/*.spec.ts"],而不是在父级文件中添加。 - Christophe Chevalier

15

你需要安装Jasmine的类型定义文件。假设你使用的是相对较新的Typescript 2版本,你可以执行以下步骤:

npm install --save-dev @types/jasmine

12

使用 Typescript@2.0 或更高版本,您可以通过 npm install 安装类型定义文件。

npm install --save-dev @types/jasmine

然后在 tsconfig.json 中使用 typeRoots 选项自动导入类型。

"typeRoots": [
      "node_modules/@types"
    ],

这种解决方案不需要在每个规范文件中导入{} from 'jasmine';。


1
很遗憾,那并不起作用。规范文件中仍然显示错误。 - dave0688

5
为了让TypeScript编译器在编译期间使用所有可见的类型定义,应该从tsconfig.json文件的compilerOptions字段完全删除types选项。
当compilerOptions字段中存在某些types条目,同时缺少jest条目时,就会出现这个问题。
因此,为了解决这个问题,你的tscongfig.json中的compilerOptions字段应该在types区域包括jest或完全摆脱types。
{
  "compilerOptions": {
    "esModuleInterop": true,
    "target": "es6",
    "module": "commonjs",
    "outDir": "dist",
    "types": ["reflect-metadata", "jest"],  //<--  add jest or remove completely
    "moduleResolution": "node",
    "sourceMap": true
  },
  "include": [
    "src/**/*.ts"
  ],
  "exclude": [
    "node_modules"
  ]
}

这对我有用,我在“types”选项中有“google map types”。将该选项完全删除后,它正常工作了。 - pritesh agrawal
是的。我只需要删除类型的东西,就可以工作了!<3 - Amir Savand

3

我最新的状态是今天,发现解决这个问题最好的方法就是什么都不做……没有 typeRoots 没有 types 没有 exclude 没有 include 所有默认值似乎都很好用。实际上,在我全部删除之前,它并没有正常工作。我先前使用了:

"exclude": [
    "node_modules"
]

但是这是默认设置,所以我把它删除了。

我曾经有:

"types": [
    "node"
]

为了消除编译器警告,但现在我已经移除了它。

这个不应该有的警告是: error TS2304: Cannot find name 'AsyncIterable'. 来自于node_modules\@types\graphql\subscription\subscribe.d.ts

这非常令人讨厌,所以我在tsconfig中做了以下操作以加载它:

"compilerOptions": {
    "target": "esnext",
}

由于它在esnext集合中,所以我目前未直接使用它,因此暂时不必担心兼容性问题。希望这不会在后面给我惹麻烦。


你不需要在 tsconfig.json 中添加 "types": ["node"],但是你应该在 tsconfig.app.json 中添加这个类型!我想你不应该再有这个警告了。 现在你可以保留 "target": "es5""target": "es6" - Christophe Chevalier

3
在我的情况下,解决方案是在我的tsconfig.json中删除typeRoots。正如您可以在TypeScript文档中阅读到的那样:

如果指定了typeRoots,则只包含在typeRoots下的软件包。


3
这个问题的解决方案与@Pace在他的答案中所写的有关。然而,它并没有解释清楚一切,如果您不介意的话,我将自己写出来。 解决方法: 添加以下行:
///<reference path="./../../../typings/globals/jasmine/index.d.ts"/>

hero.spec.ts文件的开头修复问题。路径指向typings文件夹(存储所有类型定义)。
要安装类型定义,您需要在项目根目录下创建typings.json文件,并将以下内容加入其中:
{
  "globalDependencies": {
    "core-js": "registry:dt/core-js#0.0.0+20160602141332",
    "jasmine": "registry:dt/jasmine#2.2.0+20160621224255",
    "node": "registry:dt/node#6.0.0+20160807145350"
  }
}

运行typings install命令(其中typings是NPM包)。


4
这是一种非标准的做法。默认的tslint规则会阻止引用路径。请使用tsconfig文件指向node_modules。 - FlavorScape

2

只需要按照以下步骤,在包含多个node_modules的Lerna Mono-repo中获取@types:

npm install -D @types/jasmine

然后在每个模块或应用程序的tsconfig文件中

"typeRoots": [
  "node_modules/@types",
  "../../node_modules/@types" <-- I added this line
],

默认情况下,所有可见的“@types”包都包含在编译中。任何封闭文件夹中的node_modules/@types中的包都被认为是可见的;具体来说,这意味着./node_modules/@types/、../node_modules/@types/、../../node_modules/@types/等文件夹中的包。请参阅官方文档 - Christophe Chevalier

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接