I am testing a component and I cannot figure out why a test is failing. The console.log()
clearly shows the function being called. I think it has something to do with the subscribe()
call but am not sure how to correct my test:
My component:
async deleteDocument( document : IMergedDocument ) {
const key = document.fileKey;
const className = document.className
const confirm = await this.modalCtrl.create({
component: AwakenModal,
componentProps: {
title: `Are you sure you want to delete ${document.name}?`,
subtitle: 'Deletions are irreversible.',
type: 'confirm',
urgent: true
},
cssClass: 'small-modal'
})
await confirm.present()
const data = await confirm.onDidDismiss()
if (data?.data === 'yes') {
if (className === 'ClientDoc') {
this.s3.deleteFromS3(key).then(() => {
// What I am testing. I see this in console
this.clientDocService.destroy(document.id).subscribe(d => console.log('doc', d))
})
.catch(err => this.global.handleResponse(`Error: ${err}`))
} else if (className === 'SignedDocument') {
this.clientDocService.unlinkSignedDocument(document).subscribe(
() => this.global.handleResponse('Successfully unlinked the document from this profile', false, 'success'),
err => this.global.handleResponse(err.error, true)
)
}
}
}
My test:
describe('DocumentsPage', () => {
let component: DocumentsPage;
let fixture: ComponentFixture<DocumentsPage>;
const mockS3Service = jasmine.createSpyObj('S3_Service', ['getBucketContents', 'deleteFromS3'])
const mockModalController = jasmine.createSpyObj('ModalController', ['create'])
const mockClientDocService = jasmine.createSpyObj('ClientDocService',
['destroy', 'setDocuments', 'createClientDocIfMissing', 'addToDocuments', 'addToAWSDocs', 'fetchClientAndSignedDocuments', 'setMergedDocuments']
)
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ DocumentsPage ],
imports: [HttpClientTestingModule,],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
providers: [
{ provide: S3_Service, useValue: mockS3Service },
{ provide: ModalController, useValue: mockModalController },
ExternalDocumentsService,
{ provide: ClientDocService, useValue: mockClientDocService },
]
})
.compileComponents();
}));
beforeEach(() => {
mockClientDocService.mergedDocuments$ = of([])
fixture = TestBed.createComponent(DocumentsPage);
component = fixture.componentInstance;
fixture.detectChanges();
});
describe('deleteDocument', () => {
it('should call clientDocService.destroy when a ClientDoc', async() => {
const doc = {
id: 1,
className: 'ClientDoc',
canBeViewed: true
}
const modalSpy = jasmine.createSpyObj('Modal', ['present', 'onDidDismiss'])
mockModalController.create.and.callFake(() => modalSpy)
modalSpy.onDidDismiss.and.returnValue({data: 'yes'})
mockS3Service.deleteFromS3.and.returnValue(new Promise<void>(res => res()))
mockClientDocService.destroy.and.returnValue(of(doc))
component.deleteDocument(doc).then(d => console.log("res", d))
await fixture.whenStable()
expect(mockClientDocService.destroy).toHaveBeenCalledTimes(1)
})
})
})
I have a feeling it's a jasmine
issue but I'm just not sure how to correct the test
First you do not have await
before component.deleteDocument
call.
Second, deleteDocument
is async but it does not wait for this.clientDocService.destroy
or this.clientDocService.unlinkSignedDocument
.
The way you mix async/await and observables is very confusing. I would advice to select one or another for one method, e.g. with promises/async/await:
const data = await this.clientDocService.destroy(document.id);
console.log('doc', data);
// return {result: 'destroyed', data} -- u generally want to return smth
or with observables
// deleteDocument will return Observable
return from(confirm.onDidDismiss()).pipe(switchMap(() => {
...
return this.clientDocService.destroy(document.id);
}))