在 BsModalRef 中模拟 modal.content.onClose.subscribe
Mocking modal.content.onClose.subscribe in BsModalRef
我有一个通用的 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
的 return?例如,这是一个 content 为空的示例:
spyOn(mockModalService, 'show').and.returnValue({
id: 1,
content: null,
hide: () => {},
setClass: () => {},
onHide: new EventEmitter(),
onHidden: new EventEmitter(),
});
解决这个问题的最佳方法是什么?
为了覆盖 modal.content.onClose.subscribe((result) => {
代码部分,我将为 onClose
函数和 return 创建一个模拟 Observable 创建一个间谍。棘手的部分是,this.modalService.show
返回一个实例,这个实例需要被模拟并且应该 return 一个包含 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(),
});
我无法测试上面的代码,但我希望它能帮助理解这个想法,并且通过一些小的调整它会起作用。
我有一个通用的 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
的 return?例如,这是一个 content 为空的示例:
spyOn(mockModalService, 'show').and.returnValue({
id: 1,
content: null,
hide: () => {},
setClass: () => {},
onHide: new EventEmitter(),
onHidden: new EventEmitter(),
});
解决这个问题的最佳方法是什么?
为了覆盖 modal.content.onClose.subscribe((result) => {
代码部分,我将为 onClose
函数和 return 创建一个模拟 Observable 创建一个间谍。棘手的部分是,this.modalService.show
返回一个实例,这个实例需要被模拟并且应该 return 一个包含 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(),
});
我无法测试上面的代码,但我希望它能帮助理解这个想法,并且通过一些小的调整它会起作用。