首页 文章

使用TypeORM和Nestjs进行测试的过程,以及使用模拟进行的玩笑?

提问于
浏览
0

This question can likely be generalized to stubbing repositories in a service and how to properly test and provide coverage in the context of this question.

我正在学习更多有关测试的知识,但我仍然坚持如何正确执行涉及数据库的测试 .

我有一个用户实体定义列和一些初始验证逻辑 .

import { IsAlphanumeric, IsEmail, MinLength } from 'class-validator';
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class User {
  @PrimaryGeneratedColumn()
  public id!: number;

  @Column()
  public name!: string;

  @IsEmail()
  @Column()
  public email!: string;

  @MinLength(8)
  @Column()
  public password!: string;
}

我有一个UserService,它为实体注入了Repository .

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { validateOrReject } from 'class-validator';
import { Repository } from 'typeorm';
import { CreateUserDTO } from './dto/create-user.dto';
import { User } from './user.entity';

@Injectable()
export class UserService {
  constructor(
    @InjectRepository(User) private readonly userRepository: Repository<User>
  ) {}

  public async create(dto: CreateUserDTO) {
    const user = this.userRepository.create(dto);
    await validateOrReject(user);
    await this.userRepository.save(user);
  }

  public async findAll(): Promise<User[]> {
    return await this.userRepository.find();
  }

  public async findByEmail(email: string): Promise<User | undefined> {
    return await this.userRepository.findOne({
      where: {
        email,
      },
    });
  }
}

这是我的初步测试,所以你可以按照我的思路......

import { Test, TestingModule } from '@nestjs/testing';
import { getRepositoryToken } from '@nestjs/typeorm';
import { User } from './user.entity';
import { UserService } from './user.service';

const createMock = jest.fn((dto: any) => {
  return dto;
});

const saveMock = jest.fn((dto: any) => {
  return dto;
});

const MockRepository = jest.fn().mockImplementation(() => {
  return {
    create: createMock,
    save: saveMock,
  };
});
const mockRepository = new MockRepository();

describe('UserService', () => {
  let service: UserService;

  beforeAll(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [
        UserService,
        {
          provide: getRepositoryToken(User),
          useValue: mockRepository,
        },
      ],
    }).compile();
    service = module.get<UserService>(UserService);
  });

  it('should be defined', () => {
    expect(service).toBeDefined();
  });

  it('should not create invalid user', async () => {
    // ??
  });
});

因此,虽然我可以进行测试和一切,但我不确定我实际上应该测试什么 . 我可以明显地测试它在创建时是否有效,对于像findAll这样的其他东西,我觉得我只是在嘲笑数据库?为了正确测试它,是否需要连接到数据库,以便检查是否返回了正确的数据?

嵌套文件说"we usually want to avoid any database connection",但是没有真正测试功能吗?因为虽然我可以模拟save保存返回一个值,但我没有测试唯一列,可空数据,要设置的递增值等可能发生的任何错误......对吗?

1 回答

  • 1

    许多人认为测试数据库是不好的做法 . 但正因为什么你提到自己节省管理模拟和存根的麻烦,我几乎总是在专用的测试数据库上运行我的测试 .

    在我的开玩笑中,我清除了所有表格,然后帮助我根据需要创建具有关系的实体,以确保我的测试保持原子性 .

相关问题