We can use Injector to test any kind of service or injection point. It's possible to invoke integration tests without starting web server with fakeHttpServer api.
@Injection of abstract implementation should always deliver correct Token
@Injectable()
class ServiceA {
}
@Injectable()
class ServiceB {
}
@Injectable()
class ServiceC {
}
@Injectable()
abstract class AbstractClass {
@Inject(ServiceA)
public serviceAClass: ServiceA;
}
@Injectable()
class ImplementationA extends AbstractClass {
@Inject(ServiceB)
public config: ServiceB;
@Inject(ServiceB)
public serviceBClass: ServiceB;
}
@Injectable()
class ImplementationB extends AbstractClass {
@Inject(ServiceC)
public config: ServiceC;
@Inject(ServiceC)
public serviceCClass: ServiceC;
}
let providerA = Metadata.verifyProvider(ImplementationA);
let providerB = Metadata.verifyProvider(ImplementationB);
let parent = new Injector();
parent.createAndResolve(Metadata.verifyProvider(AbstractClass), [Metadata.verifyProvider(ServiceA)]);
let injector = new Injector(parent);
injector.createAndResolve(providerA, [Metadata.verifyProvider(ServiceB)]);
injector.createAndResolve(providerB, [Metadata.verifyProvider(ServiceC)]);
let instanceA = injector.get(ImplementationA);
let instanceB = injector.get(ImplementationB);
assert.instanceOf(instanceA.serviceAClass, ServiceA);
assert.instanceOf(instanceA.config, ServiceB);
assert.instanceOf(instanceA.serviceBClass, ServiceB);
assert.isUndefined(instanceA.serviceCClass);
assert.instanceOf(instanceB.serviceAClass, ServiceA);
assert.instanceOf(instanceB.config, ServiceC);
assert.instanceOf(instanceB.serviceCClass, ServiceC);
assert.isUndefined(instanceB.serviceBClass);
@Injectable Should inject correctly with useFactory:
@Injectable()
class A {
@Inject("logger")
private c;
constructor(private a: Logger, @Inject("logger") private b) {
}
getA(): Logger {
return this.a;
}
getB(): Logger {
return this.b;
}
getC(): Logger {
return this.c;
}
}
let provider = {
provide: "logger",
useFactory: (logger) => {
assert.instanceOf(logger, Logger);
return logger;
},
deps: [Logger]
};
let aSpy = spy(provider, "useFactory");
let injector = Injector.createAndResolve(A, [
Logger,
provider
]);
assertSpy.called(aSpy);
let a: A = injector.get(A);
assert.instanceOf(a.getA(), Logger);
assert.instanceOf(a.getB(), Logger);
assert.instanceOf(a.getC(), Logger);
@Injectable Should inject correctly to constructor and injection point with @Inject decorator
@Injectable()
class Logger {}
@Injectable()
class A {
@Inject(Logger)
private c;
constructor(private a: Logger, @Inject(Logger) private b) {
}
getA(): Logger {
return this.a;
}
getB(): Logger {
return this.b;
}
getC(): Logger {
return this.c;
}
}
let injector = Injector.createAndResolve(A, [
{provide: Logger, useClass: Logger}
]);
let a: A = injector.get(A);
assert.instanceOf(a.getA(), Logger);
assert.instanceOf(a.getB(), Logger);
assert.instanceOf(a.getC(), Logger);