【发布时间】:2019-03-18 18:13:36
【问题描述】:
这个问题很可能被概括为服务中的存根存储库以及如何在这个问题的上下文中正确测试和提供覆盖范围。
我正在学习有关测试的更多信息,但我不知道如何正确执行涉及数据库的测试。
我有一个定义列和一些初始验证逻辑的用户实体。
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 () => {
// ??
});
});
因此,虽然我可以进行测试和所有操作,但我不确定我实际上应该测试什么。我显然可以测试它是否在创建时验证,对于 findAll 等其他东西,我觉得我只是在模拟数据库?为了让我正确测试它,是否需要将它连接到数据库以便我可以检查是否返回了正确的数据?
nest 文档说“我们通常希望避免任何数据库连接”,但这样做不会违背目的,因为我们没有真正测试功能吗?因为虽然我可以模拟保存返回一个值,但我没有测试唯一列、可空数据、要设置的递增值等可能发生的任何错误......对吗?
【问题讨论】:
-
“我不确定我实际上应该测试什么”,确切地说,因为您在服务中基本上没有什么要测试的。您唯一可以测试的是您的服务是否正确调用了您希望它调用的存储库方法并使用正确的参数,为此您将使用“spyOn”或“toHaveBeenCalledWith”。 TypeORM 已经是一个经过测试的库,所以你不想测试 TypeORM。针对数据库的测试是功能测试,而不是单元测试,在这种情况下,我将以端到端的方式重新组织您的测试,调用您的 API 端点并在调用后测试数据库。
标签: testing tdd nestjs typeorm