大理石测试可观察到方法调用后发生了变化? [英] Marble testing observable that changes after a method call?
问题描述
在Angular 8中,我有一个具有只读Observable
属性的服务,该属性是从BehaviorSubject<string>
派生的,该属性包含描述服务状态的字符串.服务中还包含更改服务状态的方法.
export class StateService {
private _state = new BehaviorSubject<string>('before');
readonly state$ = this._state.asObservable();
constructor () { }
begin() { this._state.next('during'); }
finish() { this._state.next('after'); }
reset() { this._state.next('before'); }
}
我想做的是在Jasmine套件中编写大理石测试,以优雅地测试此可观察值的价值,因为它会发生变化.
let scheduler: TestScheduler;
beforeEach(() => {
scheduler = new TestScheduler((actual, expected) => {
expect(actual).toEqual(expected);
});
});
it('should flow states correctly', () => {
scheduler.run(({expectObservable, flush}) => {
const svc = setupSvc(); //Call to a function in the suite that sets up the StateService
svc.begin();
svc.finish();
svc.reset();
flush();
expectObservable(svc.state$).toBe('a-b-c-d', {
a: 'before',
b: 'during',
c: 'after',
d: 'before'
});
});
});
我尝试了调用begin
,finish
,reset
和调度程序的flush
助手的各种组合,但是期望总是只报告一个初始值(a
大理石),而没有其他人.
要实现这一目标,我缺少什么?还是大理石是测试该方法的错误方法?
订阅通过测试帮助程序生成的冷可观察结果似乎可行:
it('should flow states correctly', () => {
scheduler.run(({ expectObservable, cold }) => {
const svc = new StateService();
cold('--a-b-c', {
a: 'begin',
b: 'finish',
c: 'reset'
}).subscribe(methodName => {
svc[methodName]();
})
expectObservable(svc.state$).toBe('a-b-c-d', {
a: 'before',
b: 'during',
c: 'after',
d: 'before'
});
});
});
In Angular 8, I have a service with a readonly Observable
property, spawned from a BehaviorSubject<string>
that contains a string describing the service's state. Also in the service are methods that change the state of the service.
export class StateService {
private _state = new BehaviorSubject<string>('before');
readonly state$ = this._state.asObservable();
constructor () { }
begin() { this._state.next('during'); }
finish() { this._state.next('after'); }
reset() { this._state.next('before'); }
}
What I want to do is write marble tests in my Jasmine suite to elegantly test the value of this observable as it would change.
let scheduler: TestScheduler;
beforeEach(() => {
scheduler = new TestScheduler((actual, expected) => {
expect(actual).toEqual(expected);
});
});
it('should flow states correctly', () => {
scheduler.run(({expectObservable, flush}) => {
const svc = setupSvc(); //Call to a function in the suite that sets up the StateService
svc.begin();
svc.finish();
svc.reset();
flush();
expectObservable(svc.state$).toBe('a-b-c-d', {
a: 'before',
b: 'during',
c: 'after',
d: 'before'
});
});
});
I've tried varying combinations of calling begin
, finish
, reset
, and the scheduler's flush
helper, but the expectation always reports just the one initial value (the a
marble) and no others.
What am I missing to be able to pull this off? Or are marbles the wrong way to go about testing this?
Subscribing to a cold observable produced via the test helper seems to work:
it('should flow states correctly', () => {
scheduler.run(({ expectObservable, cold }) => {
const svc = new StateService();
cold('--a-b-c', {
a: 'begin',
b: 'finish',
c: 'reset'
}).subscribe(methodName => {
svc[methodName]();
})
expectObservable(svc.state$).toBe('a-b-c-d', {
a: 'before',
b: 'during',
c: 'after',
d: 'before'
});
});
});
这篇关于大理石测试可观察到方法调用后发生了变化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!