Is it possible to list array of component dependency injectors?

666 Views Asked by At

How do I list all the dependency injectors of a component in angular?

This requirement is for unit testing.

I have an instance of a component created as follows :

component = fixture.componentInstance();

So in my test case, I need something like

console.log(component.constructor.params) // should print all the constructor parameteres

For ex in the below code :

constructor(private _logger: LoggerService, private _router: Router,
                private _adminService: AdminService) {
}

I need to fetch array of DI's

0 -> LoggerService
1 -> Router
2 -> AdminService
3

There are 3 best solutions below

6
jtate On

You should be able to take advantage of Javascript's built in arguments object.

So if you just need the names of the classes of each dependency, you can put this in your constructor:

constructor(
    private _logger: LoggerService, 
    private _router: Router,
    private _adminService: AdminService
) {
    let dependencies = Array.from(arguments).map((item) => item.constructor.name);
}

Logging the dependencies object to the console should output:

0: "LoggerService"
1: "Router"
2: "AdminService"

If your array needs to contain the full object instead of the name of the class, just remove the .map() function from the constructor code.

0
hazan kazim On

Use this code to print out the constructor parameter. where you have to Provider to mention the services and router.

//import module services and router her 


 describe('MyComponent', () => {
  let _logger: LoggerService;
  let _router : Router;
  let _adminService :AdminService;
beforeEach(async(() => {

  TestBed.configureTestingModule({
    declarations: [
        MyComponent,
    ],
    imports: [ 
        CommonModule,
        FormsModule,
        HttpModule
  ],
  providers: [

  {provide:AdminService,  useValue: adminService},     
  {provide:Router, useValue:routerSpy} ,     
  {provide:LoggerService, useValue: logService } ,     

  ],
  }).compileComponents();

  fixture = TestBed.createComponent(MyComponent);
 component = fixture.componentInstance;
 _adminService = new AdminService(http);
  _logger = new LoggerService(http); 
}));  
    it('should create the app', async(() => {
      const fixture = TestBed.createComponent(MyComponent);
      component = fixture.componentInstance;
      const app = fixture.debugElement.componentInstance;
     console.log(component.constructor); 
    // should print all the constructor parameteres 
      expect(app).toBeTruthy();
    }));
}));
0
Bastien Caudan On

You could monkey patch your constructor before the dependency injection:

function keepConstructorDependenciesOf(MyClass) {
  // keep references to your class and your constructor
  const originalPrototype = MyClass.prototype;
  const originalConstructor = MyClass;

  // add the logic to retrieve the type of dependencies 
  MyClass = function() { 
    this.dependencies = Array.from(arguments).map(a => a.constructor.name); 
    originalConstructor.apply(this, arguments)  
  }

  // re-apply the original prototype
  MyClass.prototype = originalPrototype;

  return MyClass;
}

Component = keepConstructorDependenciesOf(Component);

// run the dependency injection
...

component = fixture.componentInstance();

expect(component.dependencies).toEqual([
  'LoggerService', 
  'Router', 
  'AdminService'
])

Some references about redefining a constuctor