繁体   English   中英

使用 NestJS 服务单元测试未找到连接“默认”

[英]Connection "default" was not found with NestJS Unit Testing of Service

我目前正在对我的 NestJS 服务进行单元测试。 我的实体称为“用户”,我建立了一个基本服务,允许我与 MS SQL 服务器交互,并在我的 Controller 中建立 GET 和 POST 端点。

虽然我能够模拟服务中使用的Repository ,但我无法在必须调用getConection()的方法中建立模拟getConnection

当我尝试使用npm run test:watch单元测试时,我收到ConnectionNotFoundError: Connection "default" was not found. 我已经研究过(实际上,从中得到了很多) How to stub EntityManager and Connection in TypeORM with Jest ,但这篇文章似乎没有详细说明未建立的连接,这是我的问题。

无论如何,这是我对相关部分的服务:

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { getConnection, Repository } from "typeorm";
import {User} from '../entities/user.entity';


@Injectable()
export class ServiceName {
  constructor(@InjectRepository(User) private usersRepository: Repository<User>) {}

  // Creating and inserting a new user into the database table using Repository
  // unit testing for this one works fine
  async createUserRepository(user: User): Promise<User> {
    const newUser = this.usersRepository.create(user); 
    return await this.usersRepository.save(newUser);
  }

  // Creating and inserting a new user into the database table using QueryBuilder and getConnection
  // unit testing for this one does not work so well 
  async createUserQueryBuilder(user: User): Promise<User> {
    await getConnection()
    .createQueryBuilder()
    .insert()
    .into(User)
    .values([
        user, 
     ])
    .execute();
    return user;  
  }

这是我用于单元测试的 spec.ts 文件:

import { Test, TestingModule } from '@nestjs/testing';
import { ServiceName } from './app_codes_rms_area.service';
import { getRepositoryToken } from '@nestjs/typeorm';
import { User } from '../entities/user.entity';
import { Connection, Repository } from 'typeorm';

describe('service tests', () => {

    const repositoryMockFactory: () => MockType<Repository<any>> = jest.fn(() => ({ 
        create: jest.fn(),
        save: jest.fn(),
        // other functions
    }));

    const mockConnectionFactory = jest.fn(() => ({
        getConnection: jest.fn().mockReturnValue({
            createQueryBuilder: jest.fn().mockReturnThis(),
            getMany: jest.fn().mockReturnValue(allUsers),
            insert: jest.fn().mockReturnThis(),
            into: jest.fn().mockReturnThis(),
            values: jest.fn().mockReturnThis(),
            execute: jest.fn().mockReturnValue(user),
        })
    }));
 
    let service: ServiceName;
    let mockRepository: MockType<Repository<User>>;
    let mockConnection: Connection;

    beforeEach(async () => {
        const module: TestingModule = await Test.createTestingModule({
            providers: [
                ServiceName,
                {
                    provide: getRepositoryToken(User), // a User Repository is injected to the service 
                    useFactory: repositoryMockFactory, // using factory ensures that a new mock is used for every test
                },
                {
                    provide: Connection,
                    useFactory: mockConnectionFactory,
                }
            ],
        }).compile();

        service = module.get<ServiceName>(ServiceName);
        mockRepository = module.get(getRepositoryToken(User));
        mockConnection = module.get<Connection>(Connection);
    });
        it('should create a new user and return it using Repository', async () => {
            // some test that passes using mockRepository
        });

        it('should create a new user and return it using QueryBuilder (with mocked Connection)', async () => {
            expect(await service.createUserQueryBuilder(user)).toEqual(user);
            expect(mockConnection.createQueryBuilder).toBeCalled();
            expect(mockConnection.createQueryBuilder()['insert']).toBeCalled();
            expect(mockConnection.createQueryBuilder()['into']).toBeCalled();
            expect(mockConnection.createQueryBuilder()['values']).toBeCalled();
            expect(mockConnection.createQueryBuilder()['execute']).toBeCalled();
        })

这是第二个测试, it('should create a new user and return it using QueryBuilder (with mocked Connection)' ,触发以下错误:

  ● service tests › Service Functions › should create a new user and return it using QueryBuilder (with mocked Connection)

    ConnectionNotFoundError: Connection "default" was not found.

      at new ConnectionNotFoundError (error/ConnectionNotFoundError.ts:8:9)
      at ConnectionManager.Object.<anonymous>.ConnectionManager.get (connection/ConnectionManager.ts:40:19)
      at Object.getConnection (index.ts:252:35)
      at ServiceName.createUserQueryBuilder (somefile:19:11)
      at Object.it (somefile:134:34)

最简单的解决方案是更改您的createUserQueryBuilder方法,如下所示:

async createUserQueryBuilder(user: User): Promise<User> {
  await this.usersRepository
    .createQueryBuilder()
    .insert()
    .into(User)
    .values([
        user, 
     ])
    .execute();
  return user;  
}

然后您可以更新存储库模拟repositoryMockFactory

const repositoryMockFactory: () => MockType<Repository<any>> = jest.fn(() => ({ 
  create: jest.fn(),
  save: jest.fn(),
  createQueryBuilder: jest.fn().mockReturnThis(),
  getMany: jest.fn().mockReturnValue(allUsers),
  insert: jest.fn().mockReturnThis(),
  into: jest.fn().mockReturnThis(),
  values: jest.fn().mockReturnThis(),
  execute: jest.fn().mockReturnValue(user),
}));

更新:

根据您的要求,您也可以这样做。

更新您的spec.ts文件,

import * as typeorm from 'typeorm';

const getConnectionSpy = jest.spyOn(typeorm, 'getConnection');
getConnectionSpy.mockImplementation(() => ({
  createQueryBuilder: jest.fn().mockReturnThis(),
  getMany: jest.fn().mockReturnValue(allUsers),
  insert: jest.fn().mockReturnThis(),
  into: jest.fn().mockReturnThis(),
  values: jest.fn().mockReturnThis(),
  execute: jest.fn().mockReturnValue(user),
}));

请注意,您必须相应地更新您的其他typeorm导入。 例如: typeorm.Connection

这只是为了让您了解如何做到这一点。 由于我没有对此进行测试,因此可能存在语法错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM