Typeorm 装饰器不是函数

Typeorm decorator is not a function

我有以下要测试的控制器:

class Album {
  public static getAlbums(): Promise<AlbumModel[]> {
    return getRepository(AlbumModel).find({ relations: ['pictures'] });
  }
}

链接到一个模型,我正在使用带有装饰器的 typeorm。这就是我使用 Jest

时出现问题的地方
import { Entity, PrimaryGeneratedColumn, Column, JoinTable, ManyToMany } from 'typeorm';
import { PicturesModel } from '../pictures/pictures.model';

@Entity({
  name: 'T_ALBUM_AL',
  synchronize: true,
})
export class AlbumModel {
  @PrimaryGeneratedColumn({
    name: 'AL_id',
  })
  id: number;

  @Column({
    name: 'AL_name',
  })
  name: string;

  @ManyToMany(() => PicturesModel, (picture: PicturesModel) => picture.id)
  @JoinTable({
    name: 'TJ_PICTURE_ALBUM_PA',
    joinColumn: {
      name: 'AL_id',
      referencedColumnName: 'id',
    },
    inverseJoinColumn: {
      name: 'PI_id',
      referencedColumnName: 'id',
    },
  })
  pictures: PicturesModel[];
}

为了测试这个控制器,我正在使用 ts-jest。这是我的单元测试:

import Album from './album.controller';

const getRepMock = jest.fn(() => ({
  find: jest.fn().mockImplementation(),
}));

jest.mock('typeorm', () => ({
  getRepository: getRepMock,
}));

describe('Album', () => {
  it('Should work', () => {
    Album.getAlbums();
    expect(getRepMock).toBeCalled();
  });
});

当我 运行 测试时,出现以下错误:

 FAIL  src/api/v1/album/album.test.ts
  ● Test suite failed to run

    TypeError: typeorm_1.PrimaryGeneratedColumn is not a function

       6 | })
       7 | export class PicturesModel {
    >  8 |   @PrimaryGeneratedColumn({
         |    ^
       9 |     name: 'PI_id',
      10 |   })
      11 |   id: number;

有什么问题吗?

这是我的一部分package.json

  "jest": {
    "preset": "ts-jest",
    "testEnvironment": "node",
    "coveragePathIgnorePatterns": [
      "/node_modules/"
    ]
  },
  "dependencies": {
    "@types/dotenv": "^8.2.0",
    "body-parser": "^1.19.0",
    "dotenv": "^8.2.0",
    "express": "^4.17.1",
    "express-boom": "^3.0.0",
    "glob": "^7.1.6",
    "morgan": "^1.10.0",
    "mysql": "^2.14.1",
    "pg": "^7.18.2",
    "reflect-metadata": "^0.1.10",
    "ts-jest": "^25.3.1",
    "typeorm": "0.2.24"
  },
  "devDependencies": {
    "@types/express": "^4.17.3",
    "@types/express-boom": "^3.0.0",
    "@types/glob": "^7.1.1",
    "@types/jest": "^25.2.1",
    "@types/morgan": "^1.9.0",
    "@types/node": "^8.0.29",
    "@types/supertest": "^2.0.8",
    "@typescript-eslint/eslint-plugin": "^2.24.0",
    "@typescript-eslint/parser": "^2.24.0",
    "eslint": "^6.8.0",
    "eslint-config-airbnb-base": "^14.1.0",
    "eslint-import-resolver-alias": "^1.1.2",
    "eslint-plugin-import": "^2.20.1",
    "eslint-plugin-module-resolver": "^0.16.0",
    "jest": "^25.3.0",
    "nodemon": "^2.0.2",
    "supertest": "^4.0.2",
    "ts-node": "3.3.0",
    "typescript": "3.3.3333",
    "typescript-eslint": "^0.0.1-alpha.0"
  }

您需要模拟 typeorm,像这样:

import { Repository, SelectQueryBuilder } from 'typeorm';
import { mock } from 'jest-mock-extended';

const repositoryMock = mock<Repository<any>>();
const qbuilderMock = mock<SelectQueryBuilder<any>>();

jest.mock('typeorm', () => {
    qbuilderMock.where.mockReturnThis();
    qbuilderMock.select.mockReturnThis();
    repositoryMock.createQueryBuilder.mockReturnValue(qbuilderMock);

    return {
        getRepository: () => repositoryMock,

        BaseEntity: class Mock {},
        ObjectType: () => {},
        Entity: () => {},
        InputType: () => {},
        Index: () => {},
        PrimaryGeneratedColumn: () => {},
        Column: () => {},
        CreateDateColumn: () => {},
        UpdateDateColumn: () => {},
        OneToMany: () => {},
        ManyToOne: () => {},
    }
})

我喜欢让尽可能多的 typeorm 自动模拟,所以我选择了不同的方法。我模拟所有 typeorm 然后只覆盖我正在使用的特定装饰器:

jest.mock('typeorm')
mocked(EntityRepository).mockImplementation(() => jest.fn())
mocked(Entity).mockImplementation(() => jest.fn())
mocked(Column).mockImplementation(() => jest.fn())
mocked(PrimaryGeneratedColumn).mockImplementation(() => jest.fn())
mocked(CreateDateColumn).mockImplementation(() => jest.fn())
mocked(UpdateDateColumn).mockImplementation(() => jest.fn())
mocked(DeleteDateColumn).mockImplementation(() => jest.fn())
mocked(OneToMany).mockImplementation(() => jest.fn())
mocked(ManyToOne).mockImplementation(() => jest.fn())
mocked(TableInheritance).mockImplementation(() => jest.fn())
mocked(ChildEntity).mockImplementation(() => jest.fn())

然后当我想模拟某些方法时 .find() 我模拟 EntityManager:

的特定方法
mocked(EntityManager.prototype.getCustomRepository).mockReturnValue(repository);
mocked(EntityManager.prototype.transaction as transactionOp).mockImplementation(async (runInTransaction) => runInTransaction(entityManager));
mocked(EntityManager.prototype.findOne).mockResolvedValue({
  id: 1,
  name: 'Cool Album',
});