Angular 2 Injector每次都会给你一个“新的”实例吗?

时间:2016-10-17 05:36:51

标签: angular

在单元测试中,我正在调用注入器并监视http对象,就像这样...

  beforeEach(async(inject([MyRepository, MockBackend, Http],(myRepository: MyRepository, backend: MockBackend, http : Http) => {

   spyOn(http,'get').and.callThrough();

    backend.connections.subscribe((conn: MockConnection) => {
      const options: ResponseOptions = new ResponseOptions({body: '[{"name":"chris"},{"name":"dave"}]'});
      conn.mockRespond(new Response(options));
    });
    TestBed.compileComponents();
    fixture = TestBed.createComponent(MyComponent);
    fixture.detectChanges();

  })));

但是当我将spyOn函数重构为这样的辅助方法时......

class myTestHelper{
  public static spyOnHttp(): void{
    inject([Http],(http : Http) => {
      spyOn(http, 'get').and.callThrough();
    });
  }
}

然后从我的测试设置中调用我的新代码(而不是直接调用spyOn)我收到以下错误...

Error: <toHaveBeenCalledWith> : Expected a spy, but got Function.

就像使用新的注入函数返回一个不同的http对象一样。但我认为他们会一样吗?如果它们不是每次使用注射器时如果创建新的角度,角度是如何知道的?

1 个答案:

答案 0 :(得分:0)

Angular2 DI为每个提供商维护一个实例。

如果在组件上提供某些服务,则此组件的每个实例都将获得自己的服务实例。 它的所有孩子都将获得相同的服务实例,除非其中一个孩子也有这个服务的提供者。

如果您在@NgModule()中提供服务,则它们将在DI根范围内提升,并且单个实例将与整个应用程序共享(同样,只要组件没有自己的同一令牌提供程序)

当多个模块提供相同的服务时,DI仍然只维护一个实例,因为稍后添加的多个提供者使用相同的令牌覆盖之前添加的那些。

延迟加载的模块获得了自己的范围,@NgModule()中的提供程序被提升。

DI开始按组件查找请求依赖项,并查找该依赖项的提供程序的根作用域的upwords,并返回它找到的第一个提供程序的serv ice实例。

令牌可以是服务的类型(类),字符串或OpaqueToken

简写形式providers: [SomeService]providers: [{provide: SomeService, useClass: SomeService}]相同,类型用作令牌(或键)(provide: SomeService),也用作值useClass: SomeService