2016-11-30 39 views
6

角2先進的測試文檔:角2提供程序爲什麼{useValue:...}克隆對象?

userServiceStub = { 
    isLoggedIn: true, 
    user: { name: 'Test User'} 
}; 

TestBed.configureTestingModule({ 
    declarations: [ WelcomeComponent ], 
// providers: [ UserService ] // NO! Don't provide the real service! 
            // Provide a test-double instead 
    providers: [ {provide: UserService, useValue: userServiceStub } ] 
}); 

fixture = TestBed.createComponent(WelcomeComponent); 
comp = fixture.componentInstance; 

// UserService actually injected into the component 
userService = fixture.debugElement.injector.get(UserService); 
componentUserService = userService; 
// UserService from the root injector 
userService = TestBed.get(UserService); 

似乎從我們明確創建的服務,userService形式injector.get()和userServiceStub是不同的對象。

it('stub object and injected UserService should not be the same',() => { 
    expect(userServiceStub === userService).toBe(false); 

    // Changing the stub object has no effect on the injected service 
    userServiceStub.isLoggedIn = false; 
    expect(userService.isLoggedIn).toBe(true); 
}); 

的文檔說,userService這裏是userServiceStub副本。這是否意味着Angular 2 DI會將所有{provide: someting, useValue: someValue}視爲克隆新對象frome someValue?爲什麼DI系統不直接使用someValue

Angular.io相關github上issue

+0

您是否在WelcomeComponent中提供了'UserService'? –

+0

@GünterZöchbauer我在root appModule中提供普通的userService。我的問題是,爲什麼不直接在這裏注入userServiceStub,而是將它克隆。 appModule中似乎沒有原始的userService。 – MaxLXJ

+0

我沒有注入一個克隆。 DI從不克隆。很難分辨您的代碼究竟發生了什麼。你能否提供一個Plunker來重現? –

回答

3

Angular2 DI爲每個提供者維護一個實例。如果多次提供一個鍵(類型,字符串或OpaqueToken),您將獲得多個實例。

在您的示例中,UserService由測試模塊提供,DI將始終從該模塊返回相同的實例,但是如果具有相同鍵的提供程序更接近請求依賴關係的位置(例如組件本身,然後從該供應商的情況下將被注入

要覆蓋測試的行爲有不同的方式,取決於具體的使用情況

一個例子:。

TestBed.overrideComponent(comp, {set /* or add */: 
    {providers: [/* new providers here */]} 
}); 

更新

有一個相關的懸而未決的問題https://github.com/angular/angular/issues/10788 看來,這實際上不能按預期工作。