首页 > 解决方案 > 开玩笑不实例化续集模型

问题描述

我正在从事后端测试任务,现在我正在为 Jest 和 Sequelize 集成而苦苦挣扎。

我们有一个现有的(并且可以工作的)Express JS API,需要用 Jest 进行测试。此 API 在 PostgreSQL 数据库中使用 Sequelize 创建/读取/更新/删除资源。

正如我所说,在本地主机和生产环境中一切正常。但是,在测试环境中,我有一些问题。Jest 可以将我的应用程序上传到 docker 容器中(使用 npm 的“testcontainers”库),发出请求并接收响应,但显然无法实例化我的模型和存储库。

我的项目文件夹树是这样的:

我的测试从 /tests/integration 和 /tests/unit 运行。

jest.config.js的是这样的:

require('@babel/register');
require('@babel/polyfill');

module.exports = {
  verbose: true,
  bail: true,
  clearMocks: true,
  collectCoverage: true,

  testEnvironment: 'node',
  collectCoverageFrom: ['./src/**'],
  coverageDirectory: './tests/jest-coverage',
  coveragePathIgnorePatterns: [
    ...
  ],

  coverageProvider: 'v8',

  moduleFileExtensions: [
    'js',
  ],

  transform: {
    '^.+\\.(js|jsx)?$': 'babel-jest',
  },
  transformIgnorePatterns: ['<rootDir>/node_modules/'],

  testMatch: [
    './**/*.test.js',
  ],

  globalSetup: '<rootDir>/tests/jest.setup.js',
};

我的jest.setup.js文件是这样的:

import { GenericContainer, Wait } from 'testcontainers';

import Constants from '../src/utilities/constants';
import {
  initializeDatabaseOnly, initializeConectionDatabaseOnly, runPendingMigration, runPendingSeed,
} from '../src/db/database';

module.exports = async () => {
  process.env.DEBUG = 'true';
  process.env.NODE_ENV = 'test';
  //Multiple env variable declarations...

const container = await new GenericContainer('postgres')
  .withEnv('POSTGRES_DATABASE', 'my-database')
  //More ommited environment definitions for the container
  .withExposedPorts(5432)
  .withWaitStrategy(Wait.forLogMessage('database system is ready to accept connections')
  .start();

  await new Promise(r => setTimeout(r, 1000));
  await initializeDatabaseOnly();

  await new Promise(r => setTimeout(r, 1000));
  await initializeConectionDatabaseOnly();

  await new Promise(r => setTimeout(r, 1000));
  await runPendingMigration();

  await new Promise(r => setTimeout(r, 1000));
  await runPendingSeed();

  await new Promise(r => setTimeout(r, 1000));
};

这种配置很有效。我可以上传一个容器,我可以通过 dbeaver 访问 postgresql 数据库中的播种机数据,例如。所以,我的模型和存储库在这里工作,对吧?当我尝试运行测试时,我的存储库调用出现错误,显然是因为测试的节点进程没有实例化。

我的.test.js文件是这样构建的:

import PaymentOrderService from '../../src/services/payment-order';
describe('Create payment order', () => {
  it('should return error when create a payment order with invalid customer', async () => {
    let response;

    try {
      response = await PaymentOrderService.create({
        order: { //The body of request, working both in Postman and cURL requests });
    } catch (err) {
      console.log(err);
    }

    expect(response.text).toBe('user_not_found');
  });

但是当容器进程尝试在数据库中创建一些数据时,它会崩溃并带有TypeError: Cannot read property 'findOne' of undefined. findOne() 是一个函数,我调用它来查找用户,然后将支付订单数据添加到数据库中(使用此用户 ID 作为外键)。

我们还对以下架构进行了一些测试,返回相同的错误:

describe('Create payment order with credit card parceled', () => {
  it('should return error to create a payment order installments amount', async () => {
   const response = await supertest(app)
      .post('/payment-order')
      .send(body)
      .set('api-access-key', 'dreqweq-1231239-aqeasd-aqwede-fakeapikey');
   const data = JSON.parse(response.error.text);
   expect(response.status).toEqual(415);
   expect(data.error).toBe('invalid-order.config.method-payment');

我们认为这是一个与 jest 并行化相关的问题,因为相同的调用在 jest 环境之外工作。我们也遇到了一个jest.isolateModules(() => { beforeAll() });问题,因此我们将 jest.config.json 从一个setupFiles:[] setupFilesAfterEnv:[]场景更改为globalSetup: ''一个,因为我们只需要一个容器运行(不是每个描述一个容器)。我不相信这是原因,但是...

有人知道如何解决这个问题吗?如果有人需要更多信息来帮助我,请问!

标签: javascriptnode.jspostgresqljestjssequelize.js

解决方案


有同样的问题。

  1. 从 jest.config.js 中删除转换:

    module.exports = {
    preset: 'ts-jest',
    testEnvironment: 'node',
    roots: ['<rootDir>/server/'],
    setupFiles: ['<rootDir>/server/testsetup.ts']
    // transform: {
    //  '^.+\\.(ts|tsx|js)$': 'babel-jest'
    // }
    

    };

  2. 更改所有导入,例如

import * as express from 'express'

import express from 'express'

对我来说,它有帮助。祝你好运。


推荐阅读