繁体   English   中英

Angular Jest 不能模拟 HTMLElement? “不是自定义元素注册表的一部分”

[英]Angular Jest can't mock HTMLElement? "not part of the custom element registry"

我正在尝试使用 Jest 28 对 Angular 11 中的指令进行单元测试。我需要模拟对图像的单击,因此我使用以下代码来模拟鼠标事件:

import { HTMLClickDirective } from "./html-click.directive";

describe('HTMLClickDirective', () => {
  it('should open a lightbox for images', () => {
    const directive = new HTMLClickDirective(null);
    
    const image = new HTMLImageElement;
    image.setAttribute('src','foo');
    let click = {target: image} as unknown as MouseEvent;
    
    directive.onClick(click);
    expect(directive.openLightbox).toHaveBeenCalled();
  });
});

Typescript 不会将任何内容标记为错误,但 Jest 抱怨:“TypeError:构造函数无效,构造函数不是自定义元素注册表的一部分”。

当我只是尝试制作一个HTMLElement并将其转换为HTMLImageElement时,同样的抱怨。 如果我只是尝试为以后的类型强制创建一个新Element ,它会抱怨“TypeError:非法构造函数”。

当我将变量赋值移出描述块时,也会发生同样的事情。

也许是 JSDOM 的事情?

编辑:正在测试的指令:

import { Directive, HostListener } from "@angular/core"
import { BsModalRef, BsModalService } from "ngx-bootstrap/modal"
import { ModalLightboxComponent } from "../components/shared/modal-lightbox/modal-lightbox.component";

/**
 * Handle click events on HTML elements inside a safe HTML content projection.
 * 
 * @example
 * ```html
 * <div [innerHtml]="..." HTMLClick></div>
 * ```
 */
@Directive({
  selector: "[HTMLClick]",
})
export class HTMLClickDirective {
  modalRef: BsModalRef;
  constructor(
    private modalService: BsModalService,
  ) {}

  /**
   * Listener for click events in any HTMLElement.
   */
  @HostListener("click", ["$event"])
  onClick($event: MouseEvent) {
    const target = $event.target as any

    switch (target.constructor) {
      case HTMLImageElement:
        $event.preventDefault()
        this.handleImageElement(target)
        break;
      case HTMLElement:
        $event.preventDefault()
        this.handleElement(target)
        break;
      default:
        break;
    }
  }

  openLightbox(img: string) {
    this.modalRef = this.modalService.show(ModalLightboxComponent, {
      animated: false,
      class: 'lightbox',
      initialState: {
        modalPath: img,
        closeModal: this.closeModal.bind(this),
      }
    });
  }
  closeModal() {
    this.modalRef?.hide();
  }
  
  private async handleImageElement(target: HTMLImageElement): Promise<void> {
    this.openLightbox(target.getAttribute('src'));
  }
  private async handleElement(target: HTMLElement): Promise<void> {
    console.log(target)
    if(target.nodeName === 'STRONG') document.querySelector('[id="' + target.innerText.toLowerCase() + '"]').scrollIntoView();
  }
}

让图像 = document.createElement('img');

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM