Currently, I am working on unit tests for an Angular application using Jasmine and Karma. One of the unit tests involves opening a modal and removing an item from a tree node.
Everything goes smoothly until the removeItem()
function is called. This function uses a confirmationDialogService
to confirm the removal of the item:
import { Injectable } from '@angular/core';
import { Subject, Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class ConfirmDialogService {
subject = new Subject<any>();
confirmThis(message: string, yesFn: () => void): any {
this.setConfirmation(message, yesFn);
}
setConfirmation(message: string, yesFn: () => void): any {
const that = this;
this.subject.next({
type: 'confirm',
text: message,
yesFn(): any {
that.subject.next(); // This will close the modal
yesFn();
}
});
}
getMessage(): Observable<any> {
return this.subject.asObservable();
}
}
Here are the relevant functions in my .ts file:
openModalInternal(itemRootNode: SiteTreeNode, detectChanges: Function) {
// Code for opening modal and handling result
}
removeItem(itemRootNode: SiteTreeNode, detectChanges: Function) {
// Code for confirming item removal
}
The main issue arises when the test reaches the part where
this.confirmDialogService.confirmThis(...)
is called with the second parameter being a function that should execute after confirmation. In this case, it's the yesFn()
function inside the confirmationDialogService
.
This leads to difficulties in spying on and expecting certain functions (such as deleteRequestTypeItem()
) within the yesFn()
. The challenge lies in triggering this confirmation and subsequent execution of the parameter function (yesFn()
).
This is the relevant section of my .spec test:
it('should remove item from tree node and show success message', fakeAsync(() => {
// Test setup and expectations
}));
Note: It's worth noting that a Subject observable is used in the confirmation service, which presents opportunities for manipulation to achieve the desired outcome.