如何在组件中伪造服务主题
2019-04-13
287
在我的服务中,我创建了一个主题“allDataChange”
allDataChange = new Subject<AllData>();
在我的组件中,我有
ngOnInit() {
...
this.detailsService.allDataChange.subscribe((data) => {
... something gets done here
});
}
在我的测试中……我不知道自己在做什么,但是每当我运行测试时,我都会看到一个 errorTypeError:this.detailsService.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