SpyOn TypeORM 存储库更改单元测试 NestJS 的返回值 [英] SpyOn TypeORM repository to change the return value for unit testing NestJS
本文介绍了SpyOn TypeORM 存储库更改单元测试 NestJS 的返回值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想对我的 TypeORM 数据库调用进行单元测试.我已经用有效数据模拟了我所有的 TypeORM 存储库.但是我想 SpyOn 存储库并更改 TypeORM 的返回值.我该怎么做?
I would like to unittest corner cases for my TypeORM database calls. I have already mocked all my TypeORM repositories with valid data. But I would like to SpyOn the repository and change the return value form TypeORM. How do I do that?
import {INestApplication} from '@nestjs/common';
import {Test} from '@nestjs/testing';
import {CommonModule} from '@src/common/common.module';
import {AuthService} from './auth.service';
import {Repository} from 'typeorm';
import {V3User} from '@src/database/entity/user.v3entity';
describe('AuthService', () => {
let service: AuthService;
let app: INestApplication;
beforeEach(async () => {
const module = await Test.createTestingModule({
imports: [CommonModule.forRoot(`${process.env.DEV_ENV}`)],
providers: [
AuthService,
{provide: 'V3USER_REPOSITORY', useValue: mockRepositoryV3User()},
],
}).compile();
app = module.createNestApplication();
await app.init();
service = module.get<AuthService>(AuthService);
});
it('test auth service - with non existing user in v3 db', async () => {
jest.spyOn(?????? , 'findOne').mockImplementation(() => undefined);
const res = await service.loginUser("bad token");
await expect(service.tokenBasedAuth('example bad token'))
.rejects.toThrow('bad token exception');
});
});
对于正常的测试用例,我像这样模拟数据库:
I mock the database like this for normal test cases:
export const mockRepositoryV3User = () => ({
metadata: {
columns: [],
relations: [],
},
findOne: async () =>
Promise.resolve({
id: 3,
email: 'email@example.com',
first_name: 'david',
last_name: 'david',
last_login: '2019-07-15',
date_joined: '2019-07-15',
}),
});
推荐答案
好的,在终于开始测试和尝试想法后,我发现这是一个有效的策略
Okay, after finally getting around to testing and playing with ideas I've found that this is a valid strategy
- 假设我们已经设置了一个具有基本属性的
PhotoEntity
,没有什么特别的(id、名称、描述等)
- Assume we have set up a
PhotoEntity
with basic properties, nothing too special (id, name, description, etc.)
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';
@Entity()
export class Photo {
@PrimaryGeneratedColumn()
id: number;
@Column({ length: 500 })
name: string;
@Column('text')
description: string;
@Column()
filename: string;
@Column('int')
views: number;
@Column()
isPublished: boolean;
}
- 设置一个
PhotoService
,如下所示(超级基本,但它会说明这一点):
- Set up a
PhotoService
such as the following (super basic but it will illustrate the point):
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Photo } from './photo.entity';
@Injectable()
export class PhotoService {
constructor(
@InjectRepository(Photo)
private readonly photoRepository: Repository<Photo>,
) {}
async findAll(): Promise<Photo[]> {
return await this.photoRepository.find();
}
}
- 我们可以
useClass: Repository
这样我们就不必做任何繁重的工作来设置用于测试的存储库类(Repository 是从 TypeORM 包中导入的.我们可以然后从模块中获取 repo 并将其保存为一个值以便于模拟并像这样设置我们的测试:
- We can
useClass: Repository
so that we don't have to do any of the heavy lifting of setting up a repository class to use for testing (Repository is imported from the TypeORM package. We can then get the repo from the module and save it to a value for easy mocking and set up our tests like so:
import { Test, TestingModule } from '@nestjs/testing';
import { PhotoService } from './photo.service';
import { getRepositoryToken } from '@nestjs/typeorm';
import { Photo } from './photo.entity';
import { Repository } from 'typeorm';
describe('PhotoService', () => {
let service: PhotoService;
// declaring the repo variable for easy access later
let repo: Repository<Photo>;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
PhotoService,
{
// how you provide the injection token in a test instance
provide: getRepositoryToken(Photo),
// as a class value, Repository needs no generics
useClass: Repository,
},
],
}).compile();
service = module.get<PhotoService>(PhotoService);
// Save the instance of the repository and set the correct generics
repo = module.get<Repository<Photo>>(getRepositoryToken(Photo));
});
it('should be defined', () => {
expect(service).toBeDefined();
});
it('should return for findAll', async () => {
// mock file for reuse
const testPhoto: Photo = {
id: 'a47ecdc2-77d6-462f-9045-c440c5e4616f',
name: 'hello',
description: 'the description',
isPublished: true,
filename: 'testFile.png',
views: 5,
};
// notice we are pulling the repo variable and using jest.spyOn with no issues
jest.spyOn(repo, 'find').mockResolvedValueOnce([testPhoto]);
expect(await service.findAll()).toEqual([testPhoto]);
});
});
- 针对指定文件或所有测试运行测试
▶ npm run test -- photo.service
> nestjs-playground@0.0.1 test ~/Documents/code/nestjs-playground
> jest "photo.service"
PASS src/photo/photo.service.spec.ts
PhotoService
✓ should be defined (17ms)
✓ should return for findAll (4ms) < -- test passes with no problem
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 3.372s, estimated 4s
Ran all test suites matching /photo.service/i.
这篇关于SpyOn TypeORM 存储库更改单元测试 NestJS 的返回值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文