开发者问题收集

如何在组件中伪造服务主题

2019-04-13
287

在我的服务中,我创建了一个主题“allDataChange”

allDataChange = new Subject<AllData>();

在我的组件中,我有

ngOnInit() {
  ...
  this.detailsService.allDataChange.subscribe((data) => {
    ... something gets done here
  });
}

在我的测试中……我不知道自己在做什么,但是每当我运行测试时,我都会看到一个 errorTypeError:this.detailsS​​ervice.allDataChange.subscribe 不是函数。

我尝试了十几件事。嗯,感觉有十几件。可能是我刚刚尝试了同一件事 12 次。目前,我不知道。

这是测试设置和测试:

describe('DetailsTabComponent', () => {
  let component: DetailsTabComponent;
  let fixture: ComponentFixture<DetailsTabComponent>;
  let appConfigServiceSpy: jasmine.SpyObj<AppConfigService>;
  let detailsServiceSpy: jasmine.SpyObj<RequisitionDetailsService>;

  beforeEach(async(() => {
    const spy = jasmine.createSpyObj('AppConfigService', ['loadAppConfig']);
    const detailsSpy = jasmine.createSpyObj('RequisitionDetailsService', ['getAllData', 'allDataChange']);
    TestBed.configureTestingModule({
      declarations: [
        DetailsTabComponent
      ],
      imports: [
        OwlDateTimeModule,
        OwlNativeDateTimeModule,
        HttpClientTestingModule
      ],
      providers: [
        {provide: AppConfigService, useValue: spy},
        {provide: RequisitionDetailsService, useValue: detailsSpy}
      ]
    })
    .compileComponents();
    appConfigServiceSpy = TestBed.get(AppConfigService);
    detailsServiceSpy = TestBed.get(RequisitionDetailsService);
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(DetailsTabComponent);
    detailsServiceSpy.getAllData.and.returnValue(goodData);
    // detailsServiceSpy.allDataChange.and.returnValue(goodData);
    component = fixture.componentInstance;
    fixture.detectChanges();
    fixture.debugElement.injector.get(RequisitionDetailsService);
  });

  it('should create', async(() => {
    const stubValue = 'http://test.test/';
    appConfigServiceSpy.loadAppConfig.and.returnValue(stubValue);
    expect(component).toBeTruthy();
  }));
});

我使用的是 Angular 6 和 jasmine-core 版本 2.99.1。 我已经尝试了两天让这个测试通过,而万能的谷歌根本没有帮助。有人能告诉我如何克服这个“blah.blah.subscribe 不是函数错误”并使这个测试通过吗?

1个回答

这看起来非常简单。您使用 jasmine 间谍来模拟服务,因此在测试中,您的组件将获得这些服务而不是真正的服务。组件并不真正关心它是什么 - 它想要从注入的任何内容中获得的东西都应该实现某些接口。该接口的一部分是返回您订阅的可观察对象的属性:

allDataChange = new Subject<AllData>();

但是当您使用 jasmine 模拟它时,您实际上所做的只是将值放入没有可观察对象的属性中:

detailsServiceSpy.allDataChange.and.returnValue(goodData);

因此,该属性实际上变成了这样:

detailsServiceSpy.allDataChange = goodData;

但是等等,您的组件在这里需要可观察对象!因此,您真正需要做的是将 Observable 放在那里,而不仅仅是一个值:

detailsServiceSpy.allDataChange.and.returnValue(of(goodData)); // <-- now that will be observable

但这还不是全部。监视属性实际上是以稍微不同的方式完成的。请参阅 此处 了解详细信息。

Alexander Leonov
2019-04-13