So I'm trying to test a Subject's behavior and it's not working, and it seems like there some things I'm not understanding correctly. Consider the following test:
it('marble testing subject test', () => {
const obs$: Subject<number> = new Subject<number>();
obs$.next(42);
obs$.next(24);
expect(obs$.asObservable()).toBeObservable(hot('xy', { x: 42, y: 24 }));
});
This fails with this error message:
Expected $.length = 0 to equal 2.
Expected $[0] = undefined to equal Object({ frame: 0, notification: Notification({ kind: 'N', value: 42, error: undefined, hasValue: true }) }).
Expected $[1] = undefined to equal Object({ frame: 10, notification: Notification({ kind: 'N', value: 24, error: undefined, hasValue: true }) }).
I think I sort of understand why: the Subject
(per documentation) only emits values after the start of the subscription. The toBeObservable()
function (I'm assuming) subscribes to the Subject
and so my 2 next
calls happened before this, so they won't emit.
So my question is, how would I test something like this? i.e. testing a series of emissions from a subject over time? Is this possible to do with marble testing? I can sort of get it to work by changing it out for a ReplaySubject
but if I do, the marble diagram has to be (xy)
instead of xy
.
Thanks.
I have this working in the context of an Angular application
My service, the key part being that I define my things as a getter, giving me a chance to actually spy on asObservable
if I just defined things$
as a property then the spy doesn't work:
@Injectable({
providedIn: 'root'
})
export class ApiService {
private things = new BehaviorSubject<Array<string>>([]);
public get things$(): Observable<boolean> {
return this.things.asObservable().pipe(map((things) => things.length > 0))
}
}
And then in my test, I guess the key part is that I am spying on the asObservable
method on the things
BehaviourSubject
. Like this:
describe('#things$', () => {
it('should ', () => {
const things. = 'a-b-a';
const expected = 't-f-t';
// spy on
spyOn(service['things'], 'asObservable').and.returnValue(hot(things, {
a: ['a', 'b'],
b: []
}));
expect(service.things$).toBeObservable(cold(expected, {
t: true,
f: false
}));
});
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With