test(integration): add tests for self-injections providers

This commit is contained in:
Micael Levi (@micalevisk)
2022-02-28 18:18:45 -04:00
parent 6e1243951f
commit d38a592ef0
3 changed files with 112 additions and 0 deletions

View File

@@ -1,7 +1,10 @@
import { RuntimeException } from '@nestjs/core/errors/exceptions/runtime.exception';
import { UnknownDependenciesException } from '@nestjs/core/errors/exceptions/unknown-dependencies.exception';
import { UnknownExportException } from '@nestjs/core/errors/exceptions/unknown-export.exception';
import { Test } from '@nestjs/testing';
import { expect } from 'chai';
import * as chai from 'chai';
import * as chaiAsPromised from 'chai-as-promised';
import {
DYNAMIC_TOKEN,
DYNAMIC_VALUE,
@@ -9,6 +12,13 @@ import {
} from '../src/dynamic/dynamic.module';
import { ExportsModule } from '../src/exports/exports.module';
import { InjectModule } from '../src/inject/inject.module';
import { InjectSameNameModule } from '../src/inject/inject-same-name.module';
import {
SelfInjectionProviderModule,
SelfInjectionProviderCustomTokenModule,
SelfInjectionForwardProviderModule,
} from '../src/self-injection/self-injection-provider.module';
chai.use(chaiAsPromised);
describe('Injector', () => {
describe('when "providers" and "exports" properties are inconsistent', () => {
@@ -24,6 +34,16 @@ describe('Injector', () => {
});
});
describe("When class injects a provider with the same as class's name", () => {
it('should compile with success', async () => {
const builder = Test.createTestingModule({
imports: [InjectSameNameModule],
});
await expect(builder.compile()).to.eventually.be.fulfilled;
});
});
describe('when Nest cannot resolve dependencies', () => {
it(`should fail with "RuntimeException"`, async () => {
try {
@@ -35,6 +55,42 @@ describe('Injector', () => {
expect(err).to.be.instanceof(RuntimeException);
}
});
describe('due to self-injection providers', () => {
it('should fail with "UnknownDependenciesException" due to self-injection via same class reference', async () => {
const builder = Test.createTestingModule({
imports: [SelfInjectionProviderModule],
});
await expect(
builder.compile(),
).to.eventually.be.rejected.and.be.an.instanceOf(
UnknownDependenciesException,
);
});
it('should fail with "UnknownDependenciesException" due to self-injection via forwardRef to the same class reference', async () => {
const builder = Test.createTestingModule({
imports: [SelfInjectionForwardProviderModule],
});
await expect(
builder.compile(),
).to.eventually.be.rejected.and.be.an.instanceOf(
UnknownDependenciesException,
);
});
it('should fail with "UnknownDependenciesException" due to self-injection via custom provider', async () => {
const builder = Test.createTestingModule({
imports: [SelfInjectionProviderCustomTokenModule],
});
await expect(
builder.compile(),
).to.eventually.be.rejected.and.be.an.instanceOf(
UnknownDependenciesException,
);
});
});
});
describe('when dynamic module', () => {

View File

@@ -0,0 +1,16 @@
import { Module, Injectable, Inject } from '@nestjs/common';
@Injectable()
class CoreService {
constructor(@Inject(CoreService.name) private readonly coreService: any) {}
}
@Module({
providers: [
{
provide: CoreService.name,
useValue: 'anything',
},
],
})
export class InjectSameNameModule {}

View File

@@ -0,0 +1,40 @@
import { Module, Injectable, Inject, forwardRef } from '@nestjs/common';
@Injectable()
class ServiceInjectingItself {
constructor(private readonly coreService: ServiceInjectingItself) {}
}
@Injectable()
class ServiceInjectingItselfForwared {
constructor(
@Inject(forwardRef(() => ServiceInjectingItself))
private readonly coreService: ServiceInjectingItself,
) {}
}
@Injectable()
class ServiceInjectingItselfViaCustomToken {
constructor(@Inject('AnotherToken') private readonly coreService: any) {}
}
@Module({
providers: [ServiceInjectingItself],
})
export class SelfInjectionProviderModule {}
@Module({
providers: [ServiceInjectingItselfForwared],
})
export class SelfInjectionForwardProviderModule {}
@Module({
providers: [
ServiceInjectingItselfViaCustomToken,
{
provide: 'AnotherToken',
useClass: ServiceInjectingItselfViaCustomToken,
},
],
})
export class SelfInjectionProviderCustomTokenModule {}