[英]What's the difference between TestBed.get and new Service(...dependencies)
The angular guide demonstrates two different ways of testing, one by calling new Service() and providing the dependencies to the constructor directly, and the second using dependency injection by calling TestBed.get(Service). angular guide演示了两种不同的测试方式,一种是调用 new Service() 并直接向构造函数提供依赖项,第二种是通过调用 TestBed.get(Service) 使用依赖注入。
Both of these seem functionally identical to me, except when I call TestBed.get() consecutively it does not call the constructor after the first call.这两个对我来说在功能上似乎相同,除非我连续调用 TestBed.get() 时它不会在第一次调用后调用构造函数。
The angular documentation also mentions that TestBed.get() is deprecated (even though the guide still references it!) and that I should use Type or InjectionToken instead, but I do not see how either of these classes could replace TestBed.get(). angular 文档还提到 TestBed.get() 已被弃用(即使指南仍然引用它!)并且我应该使用Type或InjectionToken代替,但我不知道这些类中的任何一个如何替换 TestBed.get() .
When you call TestBed.configureTestingModule({ providers: [SomeService] });
当你调用
TestBed.configureTestingModule({ providers: [SomeService] });
, this sets up an NgModule that can be used in subsequent tests. ,这将设置一个 NgModule,可用于后续测试。 If you call
TestBed.get(SomeService)
, this retrieves SomeService
from the injector and instantiates it if needed.如果你调用
TestBed.get(SomeService)
,它会从注入器中检索SomeService
并在需要时实例化它。 If it is instantiated, then the injector injects references to it's dependencies and returns a new instance of the service.如果它被实例化,则注入器注入对其依赖项的引用并返回该服务的新实例。
If SomeService
has already been instantiated, as in your case, then the TestBed does not need to create it.如果
SomeService
已经实例化,就像你的情况一样,那么 TestBed 不需要创建它。 This means that it won't call the constructor a subsequent time.这意味着它不会在后续时间调用构造函数。
To answer your question about the difference, basically they are the same if you are mocking all of your dependencies and if you don't need to access the DOM.要回答有关差异的问题,如果您正在模拟所有依赖项并且不需要访问 DOM,则它们基本上是相同的。 Instantiating classes without the TestBed is significantly faster because there isn't the overhead of loading the dependency injector for every test.
在没有 TestBed 的情况下实例化类要快得多,因为没有为每个测试加载依赖注入器的开销。
As for the TestBed.get() being deprecated, in Angular 8.0.0, only the specific overload that allows any type was deprecated (see https://github.com/angular/angular/blob/master/packages/core/testing/src/test_bed.ts#L67 ).至于已弃用的 TestBed.get(),在 Angular 8.0.0 中,仅弃用了允许任何类型的特定重载(请参阅https://github.com/angular/angular/blob/master/packages/core/testing /src/test_bed.ts#L67 )。 Instead of
get(token: any, notFoundValue?: any): any;
而不是
get(token: any, notFoundValue?: any): any;
the signature was changed to get<T>(token: Type<T> | InjectionToken<T>, notFoundValue?: T, flags?: InjectFlags): any;
签名更改为
get<T>(token: Type<T> | InjectionToken<T>, notFoundValue?: T, flags?: InjectFlags): any;
which means that you had to use a class reference or injection token.这意味着您必须使用类引用或注入令牌。 No strings or other things to reference something in the injector.
没有字符串或其他东西来引用注入器中的某些东西。
In Angular 9.0.0, the TestBed.get() method will be fully deprecated and you will need to use TestBed.inject
instead.在 Angular 9.0.0 中,TestBed.get() 方法将被完全弃用,您将需要使用
TestBed.inject
代替。 See https://github.com/angular/angular/blob/master/packages/core/testing/src/test_bed.ts#L65见https://github.com/angular/angular/blob/master/packages/core/testing/src/test_bed.ts#L65
Deprecated from v9.0.0 use TestBed.inject从 v9.0.0 弃用,使用 TestBed.inject
get(token: any, notFoundValue?: any): any
See how can we inject now:看看我们现在如何注入:
describe('MyAmountComponent', () => {
let component: MyAmountComponent;
let fixture: ComponentFixture<MyAmountComponent>;
let productService: ProductService;
let orderService: OrderService;
beforeEach(() => {
TestBed.configureTestingModule({
.....
})
.compileComponents();
productService = TestBed.inject(ProductService);
orderService = TestBed.inject(OrderService);
});
Just adding so might can help someone.只是添加所以可能可以帮助某人。
get is deprecated: from v9.0.0 use TestBed.inject (deprecation) get 已弃用:从 v9.0.0 开始使用 TestBed.inject(弃用)
let valueServiceSpy: jasmine.SpyObj<ValueService>;
beforeEach(() => {
const spy = jasmine.createSpyObj('ValueService', ['getValue']);
TestBed.configureTestingModule({
providers: [
{ provide: ValueService, useValue: spy }
]
});
// This is new way to inject Spied Service
valueServiceSpy = TestBed.inject(ValueService) as jasmine.SpyObj<ValueService>;
});
and then in tests然后在测试中
it('#getValue should return stubbed value from a spy', () => {
valueServiceSpy.getValue.and.returnValue(yourValue);
...
});
Official Doc: https://v9.angular.io/guide/testing#angular-testbed官方文档: https : //v9.angular.io/guide/testing#angular-testbed
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.