[NestJS][Jest] Exceeded timeout of 5000 ms for a hookfalse
Describe the bug
My team has written multiple Jest tests in our NestJS/MikroORM backend with no issues. However, no matter what we try, we're getting the following error ONLY in our test file access.spec.ts: Exceeded timeout of 5000 ms for a hookfalse.
Stack trace
FAIL src/access/access.spec.ts (8.205 s)
● AccessTest › should be defined
thrown: "Exceeded timeout of 5000 ms for a hookfalse.
Use jest.setTimeout(newTimeout) to increase the timeout value, if this is a long-running test."
72 | }) as AccessGrant;
73 |
> 74 | beforeAll(async () => {
| ^
75 | mockedMikroORM = mock<MikroORM>('mikro orm');
76 | mockedAccessGrantRepository = mock<EntityRepository<AccessGrant>>('grant repository');
77 | mockedPermissionRepository = mock<EntityRepository<Permission>>('permission repository');
at access/access.spec.ts:74:3
at Object.<anonymous> (access/access.spec.ts:20:1)
access.service.ts snippet
@Injectable()
export class AccessService {
private readonly logger = new Logger('access-service');
constructor(
private readonly orm: MikroORM,
@InjectRepository(AccessGrant)
private accessGrantRepository: EntityRepository<AccessGrant>,
@InjectRepository(Permission)
private permissionRepository: EntityRepository<Permission>,
@InjectRepository(RolePermission)
private rolePermissionRepository: RolePermissionRepository,
@InjectRepository(Role)
private roleRepository: EntityRepository<Role>,
@InjectRepository(RoleMembership)
private roleMembershipRepository: EntityRepository<RoleMembership>,
private organizationMembershipService: OrganizationMembershipService,
) {}
...
}
access.spec.ts snippet
describe('AccessTest', () => {
let accessService: AccessService;
let mockedMikroORM: Mock<MikroORM>;
let mockedAccessGrantRepository: Mock<EntityRepository<AccessGrant>>;
let mockedPermissionRepository: Mock<EntityRepository<Permission>>;
let mockedRolePermissionRepository: Mock<RolePermissionRepository>;
let mockedRoleRepository: Mock<EntityRepository<Role>>;
let mockedRoleMembershipRepository: Mock<EntityRepository<RoleMembership>>;
let mockedOrganizationMembershipService: Mock<OrganizationMembershipService>;
beforeEach(async () => {
mockedMikroORM = mock<MikroORM>('mikro orm');
mockedAccessGrantRepository = mock<EntityRepository<AccessGrant>>('grant repository');
mockedPermissionRepository = mock<EntityRepository<Permission>>('permission repository');
mockedRolePermissionRepository = mock<RolePermissionRepository>('role permission repository');
mockedRoleRepository = mock<EntityRepository<Role>>('role repository');
mockedRoleMembershipRepository = mock<EntityRepository<RoleMembership>>(
'role membership repository',
);
mockedOrganizationMembershipService = mock<OrganizationMembershipService>(
'organization membership service',
);
const module: TestingModule = await Test.createTestingModule({
providers: [
AccessService,
{
provide: MikroORM,
useValue: instance(mockedMikroORM),
},
{
provide: OrganizationMembershipService,
useValue: instance(mockedOrganizationMembershipService),
},
{
provide: getRepositoryToken(AccessGrant),
useValue: mockedAccessGrantRepository,
},
{
provide: getRepositoryToken(Permission),
useValue: mockedPermissionRepository,
},
{
provide: getRepositoryToken(RolePermission),
useValue: mockedRolePermissionRepository,
},
{
provide: getRepositoryToken(Role),
useValue: mockedRoleRepository,
},
{
provide: getRepositoryToken(RoleMembership),
useValue: mockedRoleMembershipRepository,
},
],
}).compile();
accessService = module.get(AccessService);
});
it('should be defined', () => {
expect(accessService).toBeDefined();
});
});
To Reproduce Steps to reproduce the behavior:
- Create NestJS service with MikroORM entities. Must contain one custom repository and one service injection from elsewhere.
- Instantiate mocks in a
beforeEachorbeforeAll. - Run the test, and maybe this error will occur.
As mentioned above, we're not entirely sure why this error is happening or where it's coming from considering we've followed steps 1-3 in other services within our codebase with no errors.
In light of it being difficult to reproduce this issue, any pointers would be appreciated!
Expected behavior The test should run with no timeouts since all entities, repos, and MikroORM seem to be sufficiently mocked. A timeout implies something is trying to access the network or running an infinite loop.
Additional context We've tried:
- Providing the MikroORM mock with the following instantiation:
{
provide: MikroORM,
useValue: MikroORM.init(
defineConfig({
connect: false,
clientUrl: "test",
schema: "test",
entities: [
AccessGrant,
Permission,
Role,
RoleMembership,
RolePermission,
OrganizationMembership,
],
driver: PostgreSqlDriver,
})
)
},
- Commenting out
OrganizationMembershipServicefrom everywhere in the module. - Commenting out the
TestingModuleinstantiation from the test file. This lets the test run successfully, so that implies the issue is somewhere in theawait Test.createTestingModulecall. - Removing the
MikroORMdependency from theaccess.service.tsconstructor and removing it from the test module. - Changing the timeout to 60s via
jest.setTimeout(60000);.
- Setting timeout is not a viable solution because there are no asynchronous processes running in the setup hook. Also, it doesn't fix the issue.
- We've refactored our codebase, so circular dependencies are likely not the issue here either.
Versions
| Dependency | Version |
|---|---|
| node | 18 |
| typescript | ^4.9.0 |
| mikro-orm | ^5.6.11 |
| nestjs | ^9.3.9 |
Thanks in advance!
Can you please provide a complete repro as a github repo?
@B4nan Got it to repro here
@B4nan Let me know when you take a look, still can't figure it out. You might have more context on the error, especially since we're trying to mock MikroORM. Thanks.
Looks like this is a problem with jest itself, see https://github.com/jestjs/jest/issues/11607#issuecomment-877076592 for a possible workaround.