[英]Spy on the result of an Observable Subscription with Jasmine
我是 Jasmine 单元测试一个使用 Observables 的角度组件。 我的组件有我正在测试的这个生命周期钩子:
ngOnInit() {
this.dataService.getCellOEE(this.cell).subscribe(value => this.updateChart(value));
}
我有一个测试来确保 getCellOEE 已被调用,但现在我想检查当 observable 使用新值解析时是否调用了 updateChart。 这是我到目前为止:
let fakeCellService = {
getCellOEE: function (value): Observable<Array<IOee>> {
return Observable.of([{ time: moment(), val: 67 }, { time: moment(), val: 78 }]);
}
};
describe('Oee24Component', () => {
let component: Oee24Component;
let service: CellService;
let injector: Injector;
let fixture: ComponentFixture<Oee24Component>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [Oee24Component],
providers: [{ provide: CellService, useValue: fakeCellService }]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(Oee24Component);
component = fixture.componentInstance;
injector = getTestBed();
service = injector.get(CellService)
fixture.detectChanges();
spyOn(service, 'getCellOEE').and.returnValue({ subscribe: () => { } });
spyOn(component, 'updateChart');
});
it('should get cell oee on init', () => {
component.ngOnInit();
expect(service.getCellOEE).toHaveBeenCalled();
});
it('should update chart on new data', () => {
component.ngOnInit();
expect(component.updateChart).toHaveBeenCalled();
});
});
但是,我收到错误:
chrome 56.0.2924 (Windows 10 0.0.0) Oee24Component 应该更新新数据图表失败
预期间谍 updateChart 已被调用。
大概这是一个时间问题,因为当测试检查时,observable 不一定解决? 如果是这种情况,我该如何正确设置?
这是我的组件:
@Component({
selector: 'app-oee24',
templateUrl: './oee24.component.html',
styleUrls: ['./oee24.component.css']
})
export class Oee24Component implements OnInit {
public barChartData: any[] = [{ data: [], label: 'OEE' }];
constructor(public dataService: CellService) { }
ngOnInit() {
this.dataService.getCellOEE(this.cell).subscribe(value => this.updateChart(value));
}
updateChart(data: Array<IOee>) {
this.barChartData[0].data = data.map(val => val.val);
}
}
你有没有想过解决办法? 使用jasmine-marbles
包和complete
事件怎么样?
it('should update chart on new data', () => {
const obs$ = cold('--a-|');
spyOn(service, 'getCellOEE').and.returnValue(obs$);
component.ngOnInit();
obs$.subscribe({
complete: () => {
expect(component.updateChart).toHaveBeenCalledWith('a');
}
});
});
不确定这是否是最好的方法,但我已经看到它在我正在从事的项目中工作。 该方法基本上是获取对提供给 subscribe 方法的回调函数的引用,并手动调用它以模拟观察者发出值:
it('should update chart on new data', () => {
component.ngOnInit();
// this is your mocked observable
const obsObject = service.getCellOEE.calls.mostRecent().returnValue;
// expect(obsObject.subscribe).toHaveBeenCalled() should pass
// get the subscribe callback function you provided in your component code
const subscribeCb = obsObject.subscribe.calls.mostRecent().args[0];
// now manually call that callback, you can provide an argument here to mock the "value" returned by the service
subscribeCb();
expect(component.updateChart).toHaveBeenCalled();
});
代替
spyOn(service, 'getCellOEE').and.returnValue({ subscribe: () => { } });
你可以试试
spyOn(service, 'getCellOEE').and.returnValue( {subscribe: (callback) => callback()});
fixture.detectChanges
触发器ngOnInit
。 所以,没有必要要求ngOnInit
如果手动fixture.detectChanges
被执行。
检查方法是否被调用是一种不好的做法。 相反,检查代码执行的预期结果更可靠。
在spyOn(service, 'getCellOEE').and.returnValue({ subscribe: () => { } });
行中spyOn(service, 'getCellOEE').and.returnValue({ subscribe: () => { } });
因为fakeCellService
已经正确地fakeCellService
了该服务。
测试的代码是异步的,所以我们需要等到它被执行。 await fixture.whenStable();
正是这样做的。
所以,结果测试:
const fakeData = [{ time: moment(), val: 67 }, { time: moment(), val: 78 }];
const expectedChartData = [67, 78];
const fakeCellService = {
getCellOEE: function (value): Observable<Array<IOee>> {
return Observable.of(fakeData);
}
};
describe('Oee24Component', () => {
let component: Oee24Component;
let service: CellService;
let injector: Injector;
let fixture: ComponentFixture<Oee24Component>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [Oee24Component],
providers: [{ provide: CellService, useValue: fakeCellService }]
})
.compileComponents();
}));
beforeEach(async () => {
fixture = TestBed.createComponent(Oee24Component);
component = fixture.componentInstance;
fixture.detectChanges();
await fixture.whenStable();
});
it('maps and saves value from the CellService.getCellOEE to barChartData[0].data when initialized', () => {
expect(component.barChartData[0].data).toEqual(expectedChartData);
});
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.