我有一个通用的ModalConfirm (ngx-bootstrap)组件,看起来像这样:
export class ModalConfirmComponent {
public active = false;
public body: string | undefined | null;
public title: string | undefined | null;
public onClose = new Subject<boolean>();
public constructor(private bsModalRef: BsModalRef) {}
public showConfirmationModal(title: string, body: string): void {
this.title = title;
this.body = body;
this.active = true;
}
public onConfirm(): void {
this.active = false;
this.onClose.next(true);
this.bsModalRef.hide();
}
public onCancel(): void {
this.active = false;
this.onClose.next(false);
this.bsModalRef.hide();
}
public hideConfirmationModal(): void {
this.active = false;
this.onClose.next(undefined);
this.bsModalRef.hide();
}
}
从服务调用,如下所示:
addElementWithConfirmation(
course: ICourse | undefined | null,
courseContents: ICourseContent[] | undefined | null,
selectedCourseContentUid: string | undefined | null,
selectedCourseContentElementUid: string,
selectedCourseModule: number | undefined | null,
showAddElementMenu: boolean,
courseContentElementMethod: CourseContentElementsMap,
confirmElementReplacementModalBody: string
): void {
if (
course &&
courseContents &&
selectedCourseContentUid &&
!UtilService.isNullOrUndefined(selectedCourseModule)
) {
if (
this.canCourseContentElementBeAdded(
courseContentElementMethod,
courseContents,
selectedCourseContentUid
)
) {
const modal = this.modalService.show(ModalConfirmComponent);
if (modal && modal.content) {
modal.content.showConfirmationModal(
CONFIRM_MODAL_TITLE,
confirmElementReplacementModalBody
);
modal.content.onClose.subscribe((result) => {
if (result) {
this.hideAddElementMenu(showAddElementMenu);
courseContents = ADD_COURSE_CONTENT_ELEMENT_MAP[courseContentElementMethod](
(courseContents as unknown) as ICourseContent[],
selectedCourseContentElementUid,
selectedCourseContentUid
);
} else {
this.hideAddElementMenu(showAddElementMenu);
}
});
}
}
}
我现在面临的问题是围绕测试,modal.content.onClose.subscribe((result) => {
下的所有内容目前都是无法访问的代码。我该如何解决这个问题?我的测试如下:
describe('addElementWithConfirmation()', () => {
it('should add element', () => {
spyOn(service, 'canCourseContentElementBeAdded').and.callThrough();
let newCourseContents: ICourseContent[] = JSON.parse(JSON.stringify(courseContents));
service.addElementWithConfirmation(
course,
newCourseContents,
newCourseContents[0].uid,
`${CourseContentElementType.AUDIO}-${UtilService.generateRandomString(10)}`,
0,
true,
CourseContentElementsMap.ADD_COURSE_CONTENT_ELEMENT_AUDIO,
'test'
);
expect(service.canCourseContentElementBeAdded).toHaveBeenCalled();
});
我知道最好的办法是模拟BsModalRef如下,但我不确定如何模拟modal.content.onClose.subscribe
的返回?例如,以下是内容的示例为空:
spyOn(mockModalService, 'show').and.returnValue({
id: 1,
content: null,
hide: () => {},
setClass: () => {},
onHide: new EventEmitter(),
onHidden: new EventEmitter(),
});
解决这个问题的最好方法是什么?
要覆盖modal.content.onClose.subscribe((result) => {
代码部分,我将为onClose
函数创建一个间谍并返回一个模拟的Observable。棘手的部分是,this.modalService.show
返回一个实例,这个实例需要被模拟,并且它应该返回一个模拟对象,该对象包含content.onClose
的间谍。
因此,需要类似的东西:
const onCloseSpy = jasmine.createSpy().and.returnValue(of({})); // Here the rxjs of operator needes to return the onClose result object istead of the empty {} object. Please change add the object based on your needs.
const contentMock = {onClose: onCloseSpy};
spyOn(mockModalService, 'show').and.returnValue({
id: 1,
content: contentMock,
hide: () => {},
setClass: () => {},
onHide: new EventEmitter(),
onHidden: new EventEmitter(),
});
我无法测试上面的代码,但我希望,它有助于理解这个想法,并进行微小的调整,它将工作。