Problem:个
当运行JEST和SuperTest时,在它到达我所描述的实际测试之前,我得到了一个错误.服务器使用启动脚本运行良好,应用程序已定义.但是在运行测试脚本时,APP是未定义的.
Background:个
- 我对打字相当陌生,这是我第一次使用任何类型的测试.
- 正如在几篇博客文章和教程中看到的那样,我希望分离服务器实例,因为我计划在不同的文件中运行多个测试.
如果你有任何建议,即使是我已经try 过的,我会再试一次,然后告诉你.我无计可施,所以任何帮助都是非常可取的.谢谢.
Error:个
FAIL src/components/users/user.test.ts
● Test suite failed to run
TypeError: Cannot read properties of undefined (reading 'listen')
6 |
7 | dbConnection();
> 8 | export const server = app.listen(config.server.port, () => {
| ^
9 | logger.info(`Server is running on port: ${config.server.port}`);
10 | });
11 |
at Object.<anonymous> (src/index.ts:8:27)
at Object.<anonymous> (src/library/exitHandler/exitHandler.ts:2:1)
at Object.<anonymous> (src/library/errorHandler/errorHandler.ts:2:1)
at Object.<anonymous> (src/middleware/validateSchema.ts:3:1)
at Object.<anonymous> (src/components/users/routes.ts:2:1)
at Object.<anonymous> (src/server.ts:2:1)
at Object.<anonymous> (src/components/users/user.test.ts:2:1)
user.test.ts个
import request from 'supertest';
import app from '../../server';
describe('User registration', () => {
it('POST /register --> return new user instance', async () => {
await request(app) // error occurs when reaching this point
.post('/user/register')
.send({
firstName: 'Thomas',
lastName: 'Haek',
email: 'thomashaek@gmail.com',
password: '12345678aA',
confirmPassword: '12345678aA'
})
.expect(201)
.then((response) => {
expect(response.body).toEqual(
expect.objectContaining({
_id: expect.any(String),
firstName: expect.any(String),
lastName: expect.any(String),
email: expect.any(String),
token: expect.any(String)
})
);
});
});
});
server.ts个
import express, { Application } from 'express';
import userRouter from './components/users/routes';
import { routeErrorHandler } from './middleware/errorHandler';
import httpLogger from './middleware/httpLogger';
import './process';
const app: Application = express();
app.use(httpLogger);
app.use(express.urlencoded({ extended: true }));
app.use(express.json());
app.use('/user', userRouter);
app.use(routeErrorHandler);
export default app
index.ts个
import { createHttpTerminator } from 'http-terminator';
import config from './config/config';
import dbConnection from './config/dbConnection';
import logger from './library/logger';
import app from './server'
dbConnection();
export const server = app.listen(config.server.port, () => {
logger.info(`Server is running on port: ${config.server.port}`);
});
export const httpTerminator = createHttpTerminator({ server });
package.json scripts个
"scripts": {
"test": "env-cmd -f ./src/config/test.env jest --watchAll",
"start": "env-cmd -f ./src/config/dev.env node build/index.js",
},
tsconfig.json个
{
"compilerOptions": {
"outDir": "./build",
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true,
"module": "commonjs",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"target": "es6",
"noImplicitAny": true,
"moduleResolution": "node",
"sourceMap": true,
},
"include": ["src/**/*"]
}
jest.config.ts个
import { Config } from 'jest';
/** @type {import('ts-jest').JestConfigWithTsJest} */
const config: Config = {
preset: 'ts-jest',
testEnvironment: 'node',
roots: ['./src'],
moduleFileExtensions: ['js', 'ts'],
clearMocks: true,
collectCoverage: true,
coverageDirectory: 'coverage',
coveragePathIgnorePatterns: ['/node_modules/', '/src/config/'],
coverageProvider: 'v8',
coverageReporters: ['json', 'text', 'lcov', 'clover'],
verbose: true
};
export default config;
exitHandler.ts个
import mongoose from 'mongoose';
import { httpTerminator, server } from '../..';
import logger from '../logger';
class ExitHandler {
public async handleExit(code: number, timeout = 5000): Promise<void> {
try {
logger.info(`Attempting graceful shutdown with code: ${code}`);
setTimeout(() => {
logger.info(`Forcing a shutdown with code: ${code}`);
process.exit(code);
}, timeout).unref();
if (server.listening) {
logger.info('Terminating HTTP connections');
await httpTerminator.terminate();
await mongoose.connection.close();
}
logger.info(`Exiting gracefully with code ${code}`);
process.exit(code);
} catch (error) {
logger.error(error);
logger.error(
`Unable to shutdown gracefully... Forcing exit with code: ${code}`
);
process.exit(code);
}
}
}
export const exitHandler = new ExitHandler();
Things I've tried:个
- 对测试和服务器脚本使用相同的环境文件(相同的错误)
- 摆弄tsconfig和jest配置文件(相同的错误)
- 使用mode.exports=app而不是导出默认应用程序或导出常量服务器=app(相同错误)
- 注释掉所有中间件和路由,只导出应用程序(相同的错误)