如何在 Jest 的自定义测试环境文件中使用 TypeScript?
Posted
技术标签:
【中文标题】如何在 Jest 的自定义测试环境文件中使用 TypeScript?【英文标题】:How to use TypeScript in a Custom Test Environment file in Jest? 【发布时间】:2020-01-29 11:19:39 【问题描述】:我需要为我的测试启用一些全局变量,因此我设置了一个自定义环境以在我的jest.config.json
中的testEnvironment
选项中使用以实现此目的。
对于我们的项目,我们有一个用于setupFilesAfterEnv
选项的 TypeScript 文件,它工作得很好,但是testEnvironment
似乎只支持 ES5。有没有办法在这样的选项中使用 TypeScript?
我使用 ES5 语法成功创建了自定义 Jest 环境,但是由于我们要注入全局变量,因此我需要 TypeScript 来声明全局命名空间,请参阅:https://***.com/a/42304473/4655076。
///...
setupFilesAfterEnv: ['<rootDir>/test/setup.ts'], // This works with ts
testEnvironment: '<rootDir>/test/customJestEnvironment.ts', // This doesn't work with ts
【问题讨论】:
【参考方案1】:您可以在项目的根目录下创建一个global.d.ts
文件。
然后您可以定义全局变量,如下所示。在我的例子中,它是一个 NestJS 应用程序,但你可以定义任何东西。
declare global
namespace NodeJS
interface Global
app: INestApplication;
这是客户端项目的另一个例子,我们定义了像innerWidth
这样的窗口属性;
declare namespace NodeJS
interface Global
innerWidth: number;
dispatchEvent: Function;
【讨论】:
需要能够设置这些变量,而不仅仅是声明类型。问题 id 基本上是如何为 Jest 提供 environment.ts。【参考方案2】:在您的 .d.ts
定义文件中:
type MyGlobalFunctionType = (name: string) => void
将成员添加到浏览器的窗口上下文中:
interface Window
myGlobalFunction: MyGlobalFunctionType
NodeJS 也一样:
declare module NodeJS
interface Global
myGlobalFunction: MyGlobalFunctionType
现在你声明根变量
declare const myGlobalFunction: MyGlobalFunctionType;
然后在一个常规的 .ts
文件中,但作为副作用导入,你实际实现它:
global/* or window */.myGlobalFunction = function (name: string)
console.log("Hey !", name);
;
最后在别处使用它:
global/* or window */.myGlobalFunction("Ayush");
myGlobalFunction("Ayush");
【讨论】:
感谢您提供实现跨测试功能共享的 hacky 解决方案。问题是关于如何使用 TypeScript 编写环境。 IE。 setupFile 但全局。【参考方案3】:您可能会觉得这很有帮助:Configure Jest global tests setup with .ts file (TypeScript)
但基本上你只能将编译好的 JS 文件作为环境传入。
你可以按照那篇文章的建议去做。但这对我来说并没有开箱即用。所以我手动编译我的环境。
即
在 package.json 中
"test": "tsc --lib es6 --target es6 --skipLibCheck -m commonjs --esModuleInterop true path/to/env.ts &&
jest --config=jest.config.js",
在 jest.config.js 中
testEnvironment: '<rootDir>/path/to/env.js', // Note JS extension.
【讨论】:
【参考方案4】:您可能知道,typescript 文件只是 javascript 的超集,以提供强大的类型检查。然而,Jest 的引擎/运行时需要您的文件为 CommonJS 格式的 javascript 文件。
您可以为这个env.ts
设置一个单独的tsconfig.env.json
。在运行 jest 测试之前编译它并在你的jest.config.js
中使用编译的env.js
。
tsc -p tsconfig.env.json && jest
我也从未见过有人在 TS 中编写配置文件。
为什么是 CommonJS ?因为 jest 本质上是在节点之上运行的。 node 支持 CommonJS 格式的 Javascript 文件。 Node 最近也开始支持 es 模块!这是一件大事!
【讨论】:
【参考方案5】:我通过使用ts-node 和以下命令解决了这个问题:
node -r ts-node/register ./node_modules/jest/bin/jest.js
这实质上是即时编译打字稿,因此 jest 接收发出的 javascript,而无需实际将打字稿源编译为 js。
您需要启用esModuleInterop
TS 编译器选项才能正常工作。
TestEnvironment.ts
import NodeEnvironment from 'jest-environment-node';
import type Config from '@jest/types';
class TestEnvironment extends NodeEnvironment
constructor(config: Config.ProjectConfig)
super(config);
// this.testPath = context.testPath;
// this.docblockPragmas = context.docblockPragmas;
public async setup(): Promise<void>
await super.setup();
console.log('SETTING UP...');
// await someSetupTasks(this.testPath);
// this.global.someGlobalObject = createGlobalObject();
// // Will trigger if docblock contains @my-custom-pragma my-pragma-value
// if (this.docblockPragmas['my-custom-pragma'] === 'my-pragma-value')
// // ...
//
public async teardown(): Promise<void>
await super.teardown();
console.log('TEARING DOWN!');
// this.global.someGlobalObject = destroyGlobalObject();
// await someTeardownTasks();
export default TestEnvironment;
但是,此解决方案将破坏 globalSetup -- 如果您使用 jest-ts
。
【讨论】:
以上是关于如何在 Jest 的自定义测试环境文件中使用 TypeScript?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 jest 不能为我正在测试的自定义 React 钩子提供 useTranslation 钩子?
如何使用不同的jest.config.js进行单元和组件测试?