TestBed.get和new Service(... dependencies)有什么区别

时间:2019-06-26 15:23:55

标签: angular typescript testing jasmine

angular guide演示了两种不同的测试方法,一种是通过调用new Service()并直接向构造函数提供依赖项,另一种是通过调用TestBed.get(Service)使用依赖项注入。

这两个函数在功能上与我完全相同,只是当我连续调用TestBed.get()时,它在第一次调用后不会调用构造函数。

angular documentation还提到不推荐使用TestBed.get()(即使指南仍然引用了它!),我应该改用TypeInjectionToken,但我确实没有看到这两个类如何替换TestBed.get()。

3 个答案:

答案 0 :(得分:3)

Deprecated from v9.0.0 use TestBed.inject

get(token: any, notFoundValue?: any): any

看看我们现在如何注射:

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

仅添加它可能会对某人有所帮助。

答案 1 :(得分:1)

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

然后在测试中

it('#getValue should return stubbed value from a spy', () => {
  valueServiceSpy.getValue.and.returnValue(yourValue);
  ...
});

官方文档:https://v9.angular.io/guide/testing#angular-testbed

答案 2 :(得分:0)

调用TestBed.configureTestingModule({ providers: [SomeService] });时,这将设置一个NgModule,可在后续测试中使用。如果您调用TestBed.get(SomeService),它将从注入器中检索SomeService并在需要时实例化它。如果将其实例化,则注入器将注入对其依赖项的引用,并返回该服务的新实例。

如果SomeService已经实例化(如您的情况),则TestBed不需要创建它。这意味着它将不会再调用构造函数。

要回答有关差异的问题,如果您嘲笑所有依赖项并且不需要访问DOM,则基本上它们是相同的。没有TestBed的实例化类的速度要快得多,因为没有为每个测试加载依赖项注入程序的开销。

对于不推荐使用的TestBed.get(),在Angular 8.0.0中,仅推荐了允许任何时间的特定重载(请参见https://github.com/angular/angular/blob/master/packages/core/testing/src/test_bed.ts#L67)。签名没有更改为get(token: any, notFoundValue?: any): any;,而是更改为get<T>(token: Type<T> | InjectionToken<T>, notFoundValue?: T, flags?: InjectFlags): any;,这意味着您必须使用类引用或注入令牌。没有字符串或其他东西可以引用注入器中的某些东西。

在Angular 9.0.0中,将完全弃用TestBed.get()方法,而您将需要使用TestBed.inject。参见https://github.com/angular/angular/blob/master/packages/core/testing/src/test_bed.ts#L65