【问题标题】:Is it possible to list array of component dependency injectors?是否可以列出组件依赖注入器的数组?
【发布时间】:2018-11-27 10:56:34
【问题描述】:

如何在 Angular 中列出组件的所有依赖注入器?

此要求适用于单元测试。

我创建了一个组件的实例,如下所示:

component = fixture.componentInstance();

所以在我的测试用例中,我需要类似

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

以下代码中的前:

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

我需要获取 DI 的数组

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

【问题讨论】:

  • by testing 你指的是什么? Karma testing?将这些添加到 TestBed 提供程序数组中?
  • 是的,业力茉莉花测试。基本上我想检查组件是否注入特定服务。
  • 您应该测试行为,而不是实施,恕我直言。

标签: javascript angular typescript karma-jasmine angular2-testing


【解决方案1】:

你可以在依赖注入之前修改你的构造函数:

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

【讨论】:

    【解决方案2】:

    使用此代码打印出构造函数参数。您必须在 Provider 中提及服务和路由器。

    //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();
        }));
    }));
    

    【讨论】:

      【解决方案3】:

      您应该能够利用Javascript's built in arguments object.

      所以如果你只需要每个依赖的类名,你可以把它放在你的构造函数中:

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

      dependencies 对象记录到控制台应该会输出:

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

      如果您的数组需要包含完整的对象而不是类的名称,只需从构造函数代码中删除 .map() 函数即可。

      【讨论】:

      • 但是在constructor 函数之外我该怎么做呢?
      • @AmitChigadani 您可以在类本身中声明一个名为dependencies 的属性:dependencies = any[]; 然后在构造函数中设置this.dependencies = 而不是let dependencies =。然后,您可以在需要访问数组时随时参考this.dependencies
      • 抱歉,我不想对现有代码进行任何更改。同样在这种情况下,我可以直接在我的组件文件中添加这一行,比如this.dependencies = ['LoggerService', 'Router', 'AdminService'];,因为我知道我的构造函数中的 DI 是什么。
      • 那么你将需要一个类的实例并遍历该实例的所有键,以检查这些键是否是具有instanceof 或@987654335 的特定类的实例@.
      • @AmitChigadani 那么我不清楚你想要完成什么。在您的问题中,您说:“在下面的代码中,我需要获取 DI 数组”。我给了你一种在构造函数中获取 DI 的方法,那么你还需要什么?如果您不想更改代码,则无法从类外部访问注入,因为它们是私有的(至少从 TypeScript 的角度来看)。 trichetriche 是对的,您必须手动枚举键,而这只有在您确切知道要查找的内容时才有效。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-09-15
      • 2016-09-10
      • 2016-04-25
      • 1970-01-01
      • 1970-01-01
      • 2018-09-13
      • 1970-01-01
      相关资源
      最近更新 更多