NestJs - Jest - Testing: ConnectionNotFoundError: Connection "default" was not found
NestJs - Jest - Testing: ConnectionNotFoundError: Connection "default" was not found
我正在尝试编写一个简单的 TODO 应用测试。
这是我的服务测试class:
const mockTaskRepository = () => ({
createTask: jest.fn(),
});
describe('TasksService', () => {
let tasksService;
let taskRepository;
beforeEach(async () => {
const module = await Test.createTestingModule({
providers: [TasksService, { provide: TaskRepository, useFactory: mockTaskRepository }],
}).compile();
tasksService = await module.get<TasksService>(TasksService);
taskRepository = await module.get<TaskRepository>(TaskRepository);
});
describe('create task', () => {
it('calls taskRepository.create() and returns the result', async () => {
const createTaskDto = {
title: 'Test task',
description: 'Test desc',
};
taskRepository.createTask.mockResolvedValue('someTask');
expect(taskRepository.createTask).not.toHaveBeenCalled();
const result = await tasksService.createTask(createTaskDto);
expect(taskRepository.createTask).toHaveBeenCalledWith(createTaskDto);
expect(result).toEqual('someValue');
});
});
});
这是我的任务服务:
@Injectable()
export class TasksService {
constructor(
@InjectRepository(TaskRepository)
private taskRepository: TaskRepository,
) {}
async createTask(createTaskDto: CreateTaskDto): Promise<Task> {
const { title, description } = createTaskDto;
const task = new Task();
task.title = title;
task.description = description;
task.status = TaskStatus.IN_PROGRESS;
await task.save();
return task;
}
}
当我尝试 运行 创建任务测试时,出现以下错误。
FAIL src/tasks/tasks.service.spec.ts
● TasksService › create task › calls taskRepository.create() and returns the result
ConnectionNotFoundError: Connection "default" was not found.
at new ConnectionNotFoundError (error/ConnectionNotFoundError.ts:8:9)
at ConnectionManager.Object.<anonymous>.ConnectionManager.get (connection/ConnectionManager.ts:40:19)
at Object.getConnection (index.ts:247:35)
at Function.Object.<anonymous>.BaseEntity.getRepository (repository/BaseEntity.ts:85:72)
at Task.Object.<anonymous>.BaseEntity.save (repository/BaseEntity.ts:50:42)
at TasksService.createTask (tasks/tasks.service.ts:35:14)
at Object.<anonymous> (tasks/tasks.service.spec.ts:69:38)
Test Suites: 1 failed, 1 passed, 2 total
Tests: 1 failed, 8 passed, 9 total
有人知道代码中的错误是什么吗?
................................................
提前致谢!
如果它正在寻找连接 default
那么我假设 TypeOrmModule 配置仍然被考虑在内。如果您有 TaskEntity,请尝试将其更改为 provide: getRepositoryToken(TaskEntity)
而不是 provide: TaskRepository
。这将告诉 Nest 覆盖 @InjectRepository()
装饰器试图提供的默认仓库。
如果不是这样,您认为您可以添加 TaskService
和 TaskModule
类 吗?
您应该模拟存储库,然后调出测试模块的上下文。否则,真正的存储库正在(通过 Nest 的 DI)注入服务。
const module = await Test.createTestingModule({
providers: [
{
provide: getRepositoryToken(YourEntityClass),
useValue: mockedRepo, // or use class
},
TasksService],
}).compile();
tasksService = await module.get<TasksService>(TasksService);
// taskRepository = await module.get<TaskRepository>(TaskRepository); don't have to do that if `useValue` was used instead of factory
所以,长话短说:
在这种情况下,provide: TaskRepository
应提供给定 Injectable 的 Token
:https://docs.nestjs.com/fundamentals/custom-providers#non-class-based-provider-tokens
测试期望方法 Repository.createTask
被调用,但是方法 Service.createTask
没有调用。
修复:更新服务方法以委托给存储库方法任务创作。
// tasks.service.ts
async createTask(createTaskDto: CreateTaskDto, user: User): Promise<Task> {
return this.taskRepository.createTask(createTaskDto, user);
}
// tasks.repository.ts
async createTask(createTaskDto: CreateTaskDto, user: User): Promise<Task> {
const { title, description } = createTaskDto;
const task = new Task();
task.title = title;
task.user = user;
task.description = description;
task.status = TaskStatus.IN_PROGRESS;
await task.save();
delete task.user;
return task;
}
}
我正在尝试编写一个简单的 TODO 应用测试。
这是我的服务测试class:
const mockTaskRepository = () => ({
createTask: jest.fn(),
});
describe('TasksService', () => {
let tasksService;
let taskRepository;
beforeEach(async () => {
const module = await Test.createTestingModule({
providers: [TasksService, { provide: TaskRepository, useFactory: mockTaskRepository }],
}).compile();
tasksService = await module.get<TasksService>(TasksService);
taskRepository = await module.get<TaskRepository>(TaskRepository);
});
describe('create task', () => {
it('calls taskRepository.create() and returns the result', async () => {
const createTaskDto = {
title: 'Test task',
description: 'Test desc',
};
taskRepository.createTask.mockResolvedValue('someTask');
expect(taskRepository.createTask).not.toHaveBeenCalled();
const result = await tasksService.createTask(createTaskDto);
expect(taskRepository.createTask).toHaveBeenCalledWith(createTaskDto);
expect(result).toEqual('someValue');
});
});
});
这是我的任务服务:
@Injectable()
export class TasksService {
constructor(
@InjectRepository(TaskRepository)
private taskRepository: TaskRepository,
) {}
async createTask(createTaskDto: CreateTaskDto): Promise<Task> {
const { title, description } = createTaskDto;
const task = new Task();
task.title = title;
task.description = description;
task.status = TaskStatus.IN_PROGRESS;
await task.save();
return task;
}
}
当我尝试 运行 创建任务测试时,出现以下错误。
FAIL src/tasks/tasks.service.spec.ts
● TasksService › create task › calls taskRepository.create() and returns the result
ConnectionNotFoundError: Connection "default" was not found.
at new ConnectionNotFoundError (error/ConnectionNotFoundError.ts:8:9)
at ConnectionManager.Object.<anonymous>.ConnectionManager.get (connection/ConnectionManager.ts:40:19)
at Object.getConnection (index.ts:247:35)
at Function.Object.<anonymous>.BaseEntity.getRepository (repository/BaseEntity.ts:85:72)
at Task.Object.<anonymous>.BaseEntity.save (repository/BaseEntity.ts:50:42)
at TasksService.createTask (tasks/tasks.service.ts:35:14)
at Object.<anonymous> (tasks/tasks.service.spec.ts:69:38)
Test Suites: 1 failed, 1 passed, 2 total
Tests: 1 failed, 8 passed, 9 total
有人知道代码中的错误是什么吗?
................................................
提前致谢!
如果它正在寻找连接 default
那么我假设 TypeOrmModule 配置仍然被考虑在内。如果您有 TaskEntity,请尝试将其更改为 provide: getRepositoryToken(TaskEntity)
而不是 provide: TaskRepository
。这将告诉 Nest 覆盖 @InjectRepository()
装饰器试图提供的默认仓库。
如果不是这样,您认为您可以添加 TaskService
和 TaskModule
类 吗?
您应该模拟存储库,然后调出测试模块的上下文。否则,真正的存储库正在(通过 Nest 的 DI)注入服务。
const module = await Test.createTestingModule({
providers: [
{
provide: getRepositoryToken(YourEntityClass),
useValue: mockedRepo, // or use class
},
TasksService],
}).compile();
tasksService = await module.get<TasksService>(TasksService);
// taskRepository = await module.get<TaskRepository>(TaskRepository); don't have to do that if `useValue` was used instead of factory
所以,长话短说:
在这种情况下,provide: TaskRepository
应提供给定 Injectable 的 Token
:https://docs.nestjs.com/fundamentals/custom-providers#non-class-based-provider-tokens
测试期望方法 Repository.createTask
被调用,但是方法 Service.createTask
没有调用。
修复:更新服务方法以委托给存储库方法任务创作。
// tasks.service.ts
async createTask(createTaskDto: CreateTaskDto, user: User): Promise<Task> {
return this.taskRepository.createTask(createTaskDto, user);
}
// tasks.repository.ts
async createTask(createTaskDto: CreateTaskDto, user: User): Promise<Task> {
const { title, description } = createTaskDto;
const task = new Task();
task.title = title;
task.user = user;
task.description = description;
task.status = TaskStatus.IN_PROGRESS;
await task.save();
delete task.user;
return task;
}
}