Je voudrais avoir une configuration la plus simple qui me permette facilement de tester les boîtiers d'angle. J'ai moqué tous mes référentiels TypeORM avec des données valides. Mais je voudrais SpyOn le référentiel et changer la forme de valeur de retour TypeORM. Comment je fais ça?
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');
});
});
Je me moque de la base de données comme ceci pour les cas de test normaux:
export const mockRepositoryV3User = () => ({
metadata: {
columns: [],
relations: [],
},
findOne: async () =>
Promise.resolve({
id: 3,
email: '[email protected]',
first_name: 'david',
last_name: 'david',
last_login: '2019-07-15',
date_joined: '2019-07-15',
}),
});
D'accord, après avoir enfin testé et joué avec des idées, j'ai trouvé que c'était une stratégie valable
PhotoEntity
avec des propriétés de base, rien de trop spécial (id, nom, 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
tel que le suivant (super basique mais cela illustrera le 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
afin que nous n'ayons pas à faire le gros du travail pour configurer une classe de référentiel à utiliser pour les tests (le référentiel est importé à partir du package TypeORM. Nous pouvons ensuite récupérer le référentiel du module et l'enregistrer dans une valeur pour se moquer facilement et configurer nos tests comme suit: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
> [email protected] 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.