Nest 无法解析服务的依赖关系
Nest can't resolve dependencies of Service
我正在尝试使用模拟存储库 (typeorm) 编写服务测试,就像 nestjs 文档中提供的那样。但是我的测试技术一点都不好,我想
像这样的简单服务
apex.service.ts
@Injectable()
export class ApexService {
private _kafkaClient: ClientKafka;
constructor(
private readonly _apexRepository: ApexRepository,
private readonly _kafkaProducer: KafkaProducer,
private readonly _someService: SomeService,
) {}
// ... code here
}
...并测试它
apex.spec.ts
// ... imports
export type MockType<T> = {
[P in keyof T]?: jest.Mock<{}>;
};
export const repositoryMockFactory: () => MockType<Repository<any>> = jest.fn(
() => ({
findOne: jest.fn((entity) => entity),
create: jest.fn((entity) => entity.id),
save: jest.fn((entity) => entity.id),
// ...
}),
);
describe('ApexService', () => {
let service: ApexService;
let repositoryMock: MockType<Repository<CompanyEntity>>;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
ApexService,
{
provide: getRepositoryToken(CompanyEntity),
useFactory: repositoryMockFactory,
},
PKUchetProducer,
],
}).compile();
service = module.get<ApexService>(ApexService);
repositoryMock = module.get(getRepositoryToken(CompanyEntity));
});
it('should create company', async () => {
const dto = {
bin: '00000000000',
};
const company = {
id: 0,
};
repositoryMock.create.mockReturnValue(company);
expect(async () => service.createCompany(dto)).toEqual({
data: 0,
statusCode: 200,
});
});
});
但是我运行测试的时候出现这个错误:
● ApexService › should create company
Nest can't resolve dependencies of the ApexService (?, KafkaProducer, SomeService). Please make sure that the argument ApexRepository at index [0] is available in the RootTestModule context.
apex.respository.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Company } from '../../shared/domain/company';
import { ICompany } from '../../shared/domain/interfaces/company.interface';
import { Repository } from 'typeorm';
import { CompanyEntity } from '../entities/company.entity';
import { IApexRepository } from '../interfaces/apex-repository.interface';
@Injectable()
export class ApexRepository implements IApexRepository {
private _apexRepository: Repository<CompanyEntity>;
constructor(
@InjectRepository(CompanyEntity)
private readonly apexRepository: Repository<CompanyEntity>,
) {
this._apexRepository = this.apexRepository;
}
public async getCompanyByBIN(bin: string): Promise<Company> {
const company = await this._apexRepository.findOne({
where: { bin },
});
return Company.transform(company);
}
public async createCompany(props: ICompany): Promise<number> {
const company = this._apexRepository.create(Company.create(props));
return company.id;
}
public async updateCompany(props: ICompany): Promise<number> {
const company = await this._apexRepository.save(Company.transform(props));
return company.id;
}
}
什么问题,求解释...
将getRepositoryToken(CompanyEntity)
更改为getRepositoryToken(ApexRepository)
编辑:
由于您的存储库 class 不是自定义存储库而是标准提供程序,您必须在您的提供程序列表中注册它:
providers: [
ApexService,
{
provide: getRepositoryToken(CompanyEntity),
useFactory: repositoryMockFactory,
},
{ provide: ApexRepository, useValue: yourStub },
PKUchetProducer,
],
我正在尝试使用模拟存储库 (typeorm) 编写服务测试,就像 nestjs 文档中提供的那样。但是我的测试技术一点都不好,我想
像这样的简单服务 apex.service.ts
@Injectable()
export class ApexService {
private _kafkaClient: ClientKafka;
constructor(
private readonly _apexRepository: ApexRepository,
private readonly _kafkaProducer: KafkaProducer,
private readonly _someService: SomeService,
) {}
// ... code here
}
...并测试它 apex.spec.ts
// ... imports
export type MockType<T> = {
[P in keyof T]?: jest.Mock<{}>;
};
export const repositoryMockFactory: () => MockType<Repository<any>> = jest.fn(
() => ({
findOne: jest.fn((entity) => entity),
create: jest.fn((entity) => entity.id),
save: jest.fn((entity) => entity.id),
// ...
}),
);
describe('ApexService', () => {
let service: ApexService;
let repositoryMock: MockType<Repository<CompanyEntity>>;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
ApexService,
{
provide: getRepositoryToken(CompanyEntity),
useFactory: repositoryMockFactory,
},
PKUchetProducer,
],
}).compile();
service = module.get<ApexService>(ApexService);
repositoryMock = module.get(getRepositoryToken(CompanyEntity));
});
it('should create company', async () => {
const dto = {
bin: '00000000000',
};
const company = {
id: 0,
};
repositoryMock.create.mockReturnValue(company);
expect(async () => service.createCompany(dto)).toEqual({
data: 0,
statusCode: 200,
});
});
});
但是我运行测试的时候出现这个错误:
● ApexService › should create company
Nest can't resolve dependencies of the ApexService (?, KafkaProducer, SomeService). Please make sure that the argument ApexRepository at index [0] is available in the RootTestModule context.
apex.respository.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Company } from '../../shared/domain/company';
import { ICompany } from '../../shared/domain/interfaces/company.interface';
import { Repository } from 'typeorm';
import { CompanyEntity } from '../entities/company.entity';
import { IApexRepository } from '../interfaces/apex-repository.interface';
@Injectable()
export class ApexRepository implements IApexRepository {
private _apexRepository: Repository<CompanyEntity>;
constructor(
@InjectRepository(CompanyEntity)
private readonly apexRepository: Repository<CompanyEntity>,
) {
this._apexRepository = this.apexRepository;
}
public async getCompanyByBIN(bin: string): Promise<Company> {
const company = await this._apexRepository.findOne({
where: { bin },
});
return Company.transform(company);
}
public async createCompany(props: ICompany): Promise<number> {
const company = this._apexRepository.create(Company.create(props));
return company.id;
}
public async updateCompany(props: ICompany): Promise<number> {
const company = await this._apexRepository.save(Company.transform(props));
return company.id;
}
}
什么问题,求解释...
将getRepositoryToken(CompanyEntity)
更改为getRepositoryToken(ApexRepository)
编辑:
由于您的存储库 class 不是自定义存储库而是标准提供程序,您必须在您的提供程序列表中注册它:
providers: [
ApexService,
{
provide: getRepositoryToken(CompanyEntity),
useFactory: repositoryMockFactory,
},
{ provide: ApexRepository, useValue: yourStub },
PKUchetProducer,
],