代码之家  ›  专栏  ›  技术社区  ›  kyle

使用TypeORM和Nestjs进行测试的过程,以及使用mock的jest?

  •  0
  • kyle  · 技术社区  · 7 年前

    我正在学习更多关于测试的知识,但是我一直在学习如何正确地执行涉及数据库的测试。

        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,为实体注入存储库。

        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 () => {
            // ??
          });
        });
    

    所以,虽然我可以做测试运行和一切,我不知道我实际上应该测试什么。很明显,我可以在create上测试它是否有效,对于findAll之类的其他东西,我觉得我只是在嘲笑数据库?为了正确地测试这个,是否需要将它连接到数据库,以便检查返回的数据是否正确?

    测试功能?因为虽然我可以模拟save返回一个值,但我并不是在测试唯一列、可为null的数据、要设置的递增值等可能出现的任何错误。。。正确的?

    1 回复  |  直到 7 年前
        1
  •  12
  •   AyKarsi    7 年前

    许多人认为用db测试是不好的做法。但正是出于您提到的原因+省去了管理mock和stub的麻烦,我几乎总是在专用的测试数据库上运行测试。

    在我的jest启动中,我清除了所有的表,然后有助手帮助我根据需要创建具有关系的实体,以确保我的测试保持原子性。

        2
  •  1
  •   A Mehmeto    5 年前

    单元测试应该模拟数据库和第三方API调用。

    集成测试应该测试用真实数据库模拟的内容,并且只测试这一部分。

    端到端测试用于检查整个应用程序是否完全连接良好。

    https://martinfowler.com/articles/practical-test-pyramid.html

    推荐文章