-
Most of the testing documentation that I have found for MikroORM and NestJS is related to unit testing. Currently I am testing a service that uses injected custom repositories. This service is using these custom repositories within a transaction. As of now, my explicit transactions use the entitymanager that is provided by the RequestContext Middleware for each request, which I'm assuming is the same entitymanager instance that custom repositories use when they are injected into the service. For reference, my module for this feature looks similar to this: @Module({
imports: [
LoggerModule,
MikroOrmModule.forFeature([CasefileEntity, MunicipalityEntity]),
],
providers: [CreateCasefileProcessor], // <- this is my service
controllers: [CasefileController],
})
export class CasefilesModule {} my service: @Injectable()
export class CreateCasefileProcessor {
constructor(
private readonly _em: EntityManager, // <- this instance is from RequestContext Middleware I'm assuming?
private readonly _municipalityRepository: MunicipalityRepository, // <- also uses the same RequestContext entityManager?
private readonly _casefileRepository: CasefileRepository
) {}
async processCreateCasefileRequest(
createCasefileRequest: CreateCasefileRequest,
municipalityName: string
): Promise<CasefileResponse> {
const { year } = createCasefileRequest;
await this._em.begin();
try {
const municipality = await this._municipalityRepository.getMunicipality(
municipalityName,
year
);
const casefile = this._casefileRepository.createCasefile(
createCasefileRequest,
municipality
);
this._em.persist(casefile);
this._em.commit();
return toCasefileResponse(casefile);
} catch (error) {
await this._em.rollback();
throw error;
}
}
} If I want to test only this service, the RequestContext middleware would not exist in this context, so instead I am providing my custom repositories in my tests like this: beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [MikroOrmModule.forRoot(DatabaseConfig)],
providers: [
CreateCasefileProcessor,
{
provide: MunicipalityRepository,
useFactory: (em: EntityManager) => em.getRepository(MunicipalityEntity),
inject: [EntityManager],
},
{
provide: CasefileRepository,
useFactory: (em: EntityManager) => em.getRepository(CasefileEntity),
inject: [EntityManager],
},
],
}).compile();
orm = await module.resolve(MikroORM);
createCasefileProcessor = await module.resolve(CreateCasefileProcessor);
}); My tests are working using this method, so I'm assuming this is correct. My question is, is this a practical way to provide my custom repositories in my integration tests? assuming I understand how entitymanager is injected with RequestContext Middleware. I apologize if this is too convoluted |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
With Check the tests to see how it works if this is not enough: https://github.com/mikro-orm/mikro-orm/blob/master/tests/RequestContext.test.ts You can check the currently available fork via |
Beta Was this translation helpful? Give feedback.
With
RequestContext
helper and DI containers, you work with the global instances. The ORM will internally pick the right "contextual" one where needed, e.g. when working with UoW. This works thanks to the domain API (or in v5 viaAsyncLocalStorage
) that provides a way to access the EM fork created in a middleware, in any method that gets executed insite the domain handler - that is whatRequestContext.getEntityManager()
does.Check the tests to see how it works if this is not enough:
https://github.com/mikro-orm/mikro-orm/blob/master/tests/RequestContext.test.ts
You can check the currently available fork via
em.getContext()
which under the hood just callsRequestContext.getEntityManager()
…