why does angular 2 provider {useValue: ...} clone objects?
Angular 2 advanced testing doc:
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);
It seems that the service, userService form injector.get() and userServiceStub from we explicitly created are different Object.
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);
});
The doc say that the userService
here is a copy of userServiceStub
. Is that means that Angular 2 DI treat all {provide: someting, useValue: someValue}
as clone a new Object frome someValue
? Why DI system not use someValue
directly?
Related github issue of Angular.io.
Angular2 DI maintains a single instance per provider. If a key (type, string or OpaqueToken) is provided multiple times you'll get multiple instances.
In your example UserService
is provided by the testing module and DI will always return the same instance from this module, but if there is a provider with the same key closer to where the dependency is request (for example on the component itself, then an instance from this provider will be injected.
To override the behavior for the test there are different way, depending on the exact use case.
One example:
TestBed.overrideComponent(comp, {set /* or add */:
{providers: [/* new providers here */]}
});
Update
There is a related open issue https://github.com/angular/angular/issues/10788 Seems this actually doesn't work as expected.
链接地址: http://www.djcxy.com/p/37344.html上一篇: 使用AutoMapper解开DTO