apollo-angular
apollo-angular copied to clipboard
Testing, flushing, and async expect - how is it done?
I have a service class that looks like:
class PostDetailService {
public post: IPost;
getPostSub(): Subscription { /* ... */ }
}
post is not observable, and the template uses the injected service properties directly: {{ service.post }} for example. The template is aware of changes, but I don't know how to await for changes after flushing in tests - see below:
const getFixtures = () => {
TestBed.configureTestingModule({
providers: [GetPostsGqlService, { provide: ConsoleLoggerService, useClass: NoopLoggerService }],
imports: [ApolloTestingModule],
});
const controller: ApolloTestingController = TestBed.get(ApolloTestingController);
const service: PostDetailService = TestBed.get(PostDetailService);
return { controller, service };
};
fit('should initialise the post property', () => {
const { controller, service } = getFixtures();
const id = 1;
const fakePost = getFakePost({ overrides: { id } });
expect(service.post).toBeUndefined();
service.getPostSub(id);
controller.expectOne('getPost').flush({
data: {
post: fakePost, // { id, title, subtitle, ... }
},
});
setTimeout(() => {
// FIXME: service.post is not observable, how can this be 'waited' for? (instead of a timeout)
expect(service.post).toEqual(fakePost);
}, 200);
controller.verify();
});
What is the recommended way to deal with this?
You could use something like this:
const ongoingRequest$ = service.getPostSub(id);
/* expectOne */
// first() to take the first response that comes
// await to block execution until some response came
await ongoingRequest$.pipe(first()).toPromise();