Esta es la solución más acertada que encomtrarás aportar, pero obsérvala pausadamente y valora si se adapta a tu trabajo.
Solución:
Supongamos que tenemos un servicio muy simple que encuentra una entidad de usuario por id:
export class UserService
constructor(@InjectRepository(UserEntity) private userRepository: Repository)
async findUser(userId: string): Promise
return this.userRepository.findOne(userId);
Entonces puedes burlarte del UserRepository
con la siguiente fábrica simulada (agregue más métodos según sea necesario):
// @ts-ignore
export const repositoryMockFactory: () => MockType> = jest.fn(() => (
findOne: jest.fn(entity => entity),
// ...
));
El uso de una fábrica garantiza que se utilice una nueva simulación para cada prueba.
describe('UserService', () =>
let service: UserService;
let repositoryMock: MockType>;
beforeEach(async () =>
const module: TestingModule = await Test.createTestingModule(
providers: [
UserService,
// Provide your mock instead of the actual repository
provide: getRepositoryToken(UserEntity), useFactory: repositoryMockFactory ,
],
).compile();
service = module.get(UserService);
repositoryMock = module.get(getRepositoryToken(UserEntity));
);
it('should find a user', async () =>
const user = name: 'Alni', id: '123';
// Now you can control the return value of your mock's methods
repositoryMock.findOne.mockReturnValue(user);
expect(service.findUser(user.id)).toEqual(user);
// And make assertions on how often and with what params your mock's methods are called
expect(repositoryMock.findOne).toHaveBeenCalledWith(user.id);
);
);
Para mayor seguridad y comodidad, puede usar la siguiente escritura para sus simulaciones (parciales) (lejos de ser perfecto, podría haber una mejor solución cuando la broma comience a usar mecanografiado en las próximas versiones principales):
export type MockType =
[P in keyof T]?: jest.Mock<>;
;
Mi solución usa la base de datos de memoria sqlite donde inserto todos los datos necesarios y creo un esquema antes de cada ejecución de prueba. Por lo tanto, cada prueba cuenta con el mismo conjunto de datos y no tiene que burlarse de ningún método TypeORM:
import Test, TestingModule from "@nestjs/testing";
import CompanyInfo from '../../src/company-info/company-info.entity';
import CompanyInfoService from "../../src/company-info/company-info.service";
import Repository, createConnection, getConnection, getRepository from "typeorm";
import getRepositoryToken from "@nestjs/typeorm";
describe('CompanyInfoService', () =>
let service: CompanyInfoService;
let repository: Repository;
let testingModule: TestingModule;
const testConnectionName = 'testConnection';
beforeEach(async () =>
testingModule = await Test.createTestingModule(
providers: [
CompanyInfoService,
provide: getRepositoryToken(CompanyInfo),
useClass: Repository,
,
],
).compile();
let connection = await createConnection(
type: "sqlite",
database: ":memory:",
dropSchema: true,
entities: [CompanyInfo],
synchronize: true,
logging: false,
name: testConnectionName
);
repository = getRepository(CompanyInfo, testConnectionName);
service = new CompanyInfoService(repository);
return connection;
);
afterEach(async () =>
await getConnection(testConnectionName).close()
);
it('should be defined', () =>
expect(service).toBeDefined();
);
it('should return company info for findOne', async () =>
// prepare data, insert them to be tested
const companyInfoData: CompanyInfo =
id: 1,
;
await repository.insert(companyInfoData);
// test data retrieval itself
expect(await service.findOne()).toEqual(companyInfoData);
);
);
Me inspiré aquí: https://gist.github.com/Ciantic/be6a8b8ca27ee15e2223f642b5e01549
También descubrí que esto funcionó para mí:
export const mockRepository = jest.fn(() => (
metadata:
columns: [],
relations: [],
,
));
y
const module: TestingModule = await Test.createTestingModule(
providers: [ provide: getRepositoryToken(Entity), useClass: mockRepository ],
).compile();
Calificaciones y reseñas
Puedes añadir valor a nuestra información participando con tu veteranía en las críticas.