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
CodePudding user response:
First u 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 u 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);
}))