NestJS TypeORM 模拟存储库的数据源

Rem*_*emi 3 typescript jestjs typeorm nestjs

我正在尝试模拟一个存储库。我不想进行实际的数据库调用。我(认为我)正在关注 NestJS 的文档以及某些 stackoverflow 项目。

\n

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

\n
JwtStrategy \xe2\x80\xba validate \xe2\x80\xba throws an unauthorized exception as user cannot be found\nNest can\'t resolve dependencies of the UserEntityRepository (?). Please make sure that the argument DataSource at index [0] is available in the TypeOrmModule context.\n\nPotential solutions:\n- If DataSource is a provider, is it part of the current TypeOrmModule?\n- If DataSource is exported from a separate @Module, is that module imported within TypeOrmModule?\n  @Module({\n    imports: [ /* the Module containing DataSource */ ]\n  })\n
Run Code Online (Sandbox Code Playgroud)\n

现在据我了解,似乎 UserEntityRepository 没有被正确模拟。因为它是用户服务类中的第一个(索引 [0])依赖项:

\n

./user.service.ts

\n
JwtStrategy \xe2\x80\xba validate \xe2\x80\xba throws an unauthorized exception as user cannot be found\nNest can\'t resolve dependencies of the UserEntityRepository (?). Please make sure that the argument DataSource at index [0] is available in the TypeOrmModule context.\n\nPotential solutions:\n- If DataSource is a provider, is it part of the current TypeOrmModule?\n- If DataSource is exported from a separate @Module, is that module imported within TypeOrmModule?\n  @Module({\n    imports: [ /* the Module containing DataSource */ ]\n  })\n
Run Code Online (Sandbox Code Playgroud)\n

./jwt.strategy.ts

\n
@Injectable()\nexport class UserService {\n    constructor(\n        @InjectRepository(UserEntity)\n        private userRepository: Repository<UserEntity>\n    ) {}\n\n    async findOneBy({ username }): Promise<UserEntity> {\n        return await this.userRepository.findOneBy({ username })\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

./jwt.strategy.spect.ts

\n
@Injectable()\nexport class JwtStrategy extends PassportStrategy(Strategy) {\n  constructor(\n      private userService: UserService,\n  ) {\n    super({\n      jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),\n      secretOrKey: process.env.JWT_SECRET || config.get(\'jwt.secret\'),\n    })\n  }\n\n  async validate(payload: JwtPayload) {\n    const { username } = payload;\n    const user = await this.userService.findOneBy({username});\n\n    if (!user) {\n      throw new UnauthorizedException();\n    }\n\n    return user;\n  }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

=====更新

\n

在 Codesandbox 中创建了最小设置。

\n

https://codesandbox.io/s/xenodochial-benz-kve4eq?file=/test/jwt.test.js

\n

但不知何故,测试选项卡没有显示在沙箱中。

\n

小智 6

首先,您必须模拟数据源(如果您愿意,您可以创建一个单独的文件)

import { DataSource } from "typeorm";

// @ts-ignore
export const dataSourceMockFactory: () => MockType<DataSource> = jest.fn(() => ({
  <mock_function>: jest.fn(),
}));

export type MockType<T> = {
  [P in keyof T]?: jest.Mock<{}>;
};
Run Code Online (Sandbox Code Playgroud)

然后创建一个测试文件

describe('---MSG---', () => {
...
  let dataSourceMock: MockType<DataSource>
...
  beforeAll(async () => {
    const module = await Test.createTestingModule({
      imports: [],
      controllers: [<CONTROLLERS>],
      providers: [ <PROVIDERS>
        { provide: DataSource, useFactory: dataSourceMockFactory }],
    }).compile()
...
    dataSourceMock = module.get(DataSource);
...
  })

  describe('---MSG---', () => {
    it('---MSG---', async () => {
      await <Call mock function>
      expect(dataSourceMock.<DataSource mocked function>).toBeCalled();
    });
  })
Run Code Online (Sandbox Code Playgroud)