[英]Jest with TypeScript (Backend - Node/Express) says Cannot use import statement outside a module
I am working on Jest tests for a Node/Express TypeScript backend.我正在为 Node/Express TypeScript 后端进行 Jest 测试。 I recently learnt about global test setup which I am implementing to reduce similar variables and function calls that are executed in all test files.我最近了解了我正在实施的全局测试设置,以减少在所有测试文件中执行的类似变量和 function 调用。
So for example in the below code I want to make the app and userToken global variables and await initDatabase() function called in the tests setup file.⬇因此,例如在下面的代码中,我想使 app 和 userToken 成为全局变量,并等待在测试设置文件中调用的 initDatabase() function。⬇
import initServer from '../initServer';
import { initDatabase } from '../util/databaseHandler';
import loginWithAWS from '../util/loginWithAWS';
const app = initServer();
let userToken: any;
describe(`Test on the GET method of route `, () => {
beforeAll( async() => {
try{
await initDatabase();
userToken = await loginWithAWS('userRole');
}catch(error){
return error;
}
});
});
However, after implementing the global test setup with the variables and function then running the test on terminal/bash/cmd via the command yarn test
this error is thrown: ⬇但是,在使用变量和 function 实施全局测试设置后,然后通过命令yarn test
在终端/bash/cmd 上运行测试,抛出此错误:⬇
The solution in progress which throws the bug is implemented as shown below.抛出错误的正在进行的解决方案如下所示实现。 Your assistance will be highly valued.:您的协助将受到高度重视。:
The test setup file:测试设置文件:
testSetup.ts
⬇ testSetup.ts
import initServer from '../initServer';
import { initDatabase } from '../util/databaseHandler';
import loginWithAWS from '../util/loginWithAWS';
const initializeTestingSetup = async function() {
(global as any).app = initServer();
await initDatabase();
(global as any).userToken = await loginWithAWS('userRole');
};
module.exports = initializeTestingSetup;
Below is my jest config file for the project's tests:下面是我的项目测试的笑话配置文件:
jest.config.js
⬇ jest.config.js
⬇
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
module.exports = {
transform: {
'^.+\\.ts$': 'ts-jest',
'^.+\\.js$': 'babel-jest',
'^.+\\.mjs$': 'babel-jest',
},
moduleDirectories: ['node_modules', '<rootDir>/src'],
moduleNameMapper: {
'@controllers/(.*)': '<rootDir>/src/controllers/$1',
'@middleware/(.*)': '<rootDir>/src/middleware/$1',
'@models/(.*)': '<rootDir>/src/models/$1',
'@routes/(.*)': '<rootDir>/src/routes/$1',
'@types/(.*)': '<rootDir>/src/types/$1',
'@util/(.*)': '<rootDir>/src/util/$1',
},
globals: {
'ts-jest' : {
astTransformers: {
before: [
'ts-jest/dist/transformers/path-mapping'
]
},
}
},
globalSetup: './src/__tests__/testSetup.ts',
};
I would really appreciate your help.我将衷心感谢您的帮助。
Jest seems to have problems with ES6 import syntax in any globalSetup scripts. Jest 似乎在任何 globalSetup 脚本中都存在 ES6 导入语法问题。 I would try to change your testSetup.ts
script to use require
instead of import
so it doesn't have to be an ES6 module.我会尝试更改您的testSetup.ts
脚本以使用require
而不是import
因此它不必是 ES6 模块。 Note that you are mixing CommonJS and ES6/ESM syntax in your testSetup.js
because you have import
, but use module.exports
.请注意,您在testSetup.js
中混合了 CommonJS 和 ES6/ESM 语法,因为您有import
,但使用module.exports
。 Something like this might work perhaps (this is untested):像这样的东西可能会起作用(这是未经测试的):
const initServer = require('../initServer');
const initDatabase = require('../util/databaseHandler');
const loginWithAWS = require('../util/loginWithAWS');
const initializeTestingSetup = async function() {
(global as any).app = initServer();
await initDatabase();
(global as any).userToken = await loginWithAWS('userRole');
};
module.exports = initializeTestingSetup;
UPDATE: What about trying to make the globalsetup more compatible with ESM:更新:如何尝试使 globalsetup 与 ESM 更兼容:
import initServer from '../initServer';
import { initDatabase } from '../util/databaseHandler';
import loginWithAWS from '../util/loginWithAWS';
export default async function setup() {
(global as any).app = initServer();
await initDatabase();
(global as any).userToken = await loginWithAWS('userRole');
};
Does that help?这有帮助吗?
Ensure that package.json
has the type: module
set.确保package.json
具有type: module
集。 I'm using node14, so I've set my target and lib to have es2020
as suggested here我使用的是 node14,所以我已经按照此处的建议将目标和库设置为es2020
The tsconfig for tests:用于测试的 tsconfig:
{
"compilerOptions": {
"allowUnreachableCode": false,
"declaration": true,
"target": "es2020",
"lib": ["es2020"],
"importHelpers": true,
"incremental": true,
"module": "es2020",
"esModuleInterop": true,
"moduleResolution": "Node",
"noFallthroughCasesInSwitch": true,
"noImplicitAny": true,
"noImplicitOverride": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"resolveJsonModule": true,
"sourceMap": true,
"target": "es2020"
},
"include": ["test"],
"exclude": ["build", "node_modules"]
}
I've set esModuleInterop
to avoid any issues that might occur with default imports and set module
to es2020
(which allows for import.meta for __dirname).我设置esModuleInterop
以避免默认导入可能出现的任何问题,并将module
设置为es2020
(允许 import.meta 用于 __dirname)。
We can ask the jest config to treat modules as esm:我们可以要求 jest 配置将模块视为 esm:
{
"preset": "ts-jest",
"testEnvironment": "node",
"testMatch": ["<rootDir>/test/**/*.test.ts"],
"rootDir": ".",
"extensionsToTreatAsEsm": [".ts"],
"globalSetup": "<rootDir>/test/setup.ts",
"globals": {
"ts-jest": "./tsconfig.tests.json"
}
}
In your global setup, stick to esm exports and imports:在您的全局设置中,坚持使用 esm 导出和导入:
import express from "express";
import bodyParser from "body-parser";
import morgan from "morgan";
import helmet from "helmet";
import cors from "cors";
import PicoDb from "picodb";
const app = express();
const logger = morgan("combined");
const jsonParser = bodyParser.json();
const queryParser = bodyParser.urlencoded({ extended: true });
app.use(logger);
app.use(helmet());
app.use(queryParser);
app.use(jsonParser);
app.use(cors());
app.options("*", cors());
export { app };
export default async function globalSetup() {
const db = new PicoDb();
await db.insertMany([{ a: 1 }, { a: 2, b: 2 }]);
app.listen(3000, () => {
console.log("Server listening on port 3000");
});
}
This worked as expected when I was running the tests (with jest not exiting because I did not close the server in a teardown step).这在我运行测试时按预期工作(开玩笑没有退出,因为我没有在拆卸步骤中关闭服务器)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.