I'm trying to test a file upload. I wrapped the FileReader() into an observable according to this thread:
onFileSelected(event: any) {
this.importJsonFileToString(event.target.files[0])
.pipe(
map(jsonString => JSON.parse(jsonString)),
mergeMap(uploadData => this.httpService.postToB(uploadData)),
tap(() => console.log('after mergeMap'))
)
.subscribe();
}
private importJsonFileToString(file: any): Observable<any> {
return new Observable((subscriber: Subscriber<any>): void => {
const fileReader = new FileReader();
fileReader.readAsBinaryString(file);
fileReader.onload = (): void => {
subscriber.next((<any>fileReader).result.toString());
subscriber.complete();
};
fileReader.onerror = (error: any): void => {
subscriber.error(error);
};
});
}
The problem appears while testing the code. I use the following spec with HttpClientTestingModule to catch the Request of the inner Subscription:
it('should subscribe to inner observable with custom observable', fakeAsync(() => {
const file = new File(['{"nameA":"nameA"}'], 'testFile', { type: 'text/plain' });
const dummyEvent = { target: { files: [file] } };
const parseSpy = spyOn(JSON, 'parse').and.callThrough();
app.onFileSelected(dummyEvent);
const postRequest = httpTestingController.expectOne(req => req.method === 'POST');
postRequest.flush('');
}));
The Request does not get recorded. I also tried adding some ticks because I assume there is a problem with the asynchronous nature of the FileReader.
I also tried outer and inner request instead, which resolves without any problem:
nestedHttpCall() {
return this.httpService
.getFromA()
.pipe(mergeMap(response => this.httpService.postToB(response)))
.subscribe();
}
Spec:
it('should subscribe to inner observable', () => {
app.nestedHttpCall();
const getRequest = httpTestingController.expectOne(req => req.method === 'GET');
getRequest.flush({ nameA: 'nameA' });
const postRequest = httpTestingController.expectOne(req => req.method === 'POST');
postRequest.flush('');
expect(getRequest.request.method).toBe('GET');
expect(postRequest.request.method).toBe('POST');
});
Is my approach even correct to test the file upload?