如何从Angular规范触发输入onchange [英] how to trigger input onchange from Angular spec

查看:90
本文介绍了如何从Angular规范触发输入onchange的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个输入 HTML File 提交

<input type="file" class="custom-file-input" id="question-file-upload" formControlName="image" (change)="handleFileSelect($event)">

我想对 handleFileSelect 函数进行单元测试.但是我不知道如何触发输入的 onChange 方法.以下是我编写的 spec ,但出现错误 imageInputNE.onchange不是函数

I want to unit test handleFileSelect function. But I don't know how to trigger the onChange method of the input. Following is the spec I have written but I get error imageInputNE.onchange is not a function

fit('should keep track of image counter when an image is loaded', () => {
    let newPracticeQuestionComponent = component;
    expect(newPracticeQuestionComponent.currentImageAttachmentCount).toBe(0);
    let imageInputDE = fixture.debugElement.query(By.css("#question-file-upload"));
    expect(imageInputDE).toBeTruthy();
    spyOn(newPracticeQuestionComponent,'handleFileSelect');

    let imageInputNE:HTMLElement = imageInputDE.nativeElement as HTMLElement;
    imageInputNE.onchange(new Event("some event"));
    expect(newPracticeQuestionComponent.handleFileSelect).toHaveBeenCalled();


  });

推荐答案

请参阅Mozilla网站上的文档,事件通常由外部"源(如Buttons)触发,也可以通过编程方式触发,例如通过调用HTMLElement.元素的click()方法.或通过定义事件,然后使用EventTarget.dispatchEvent()将其发送到指定的目标.

Referring to documentation at Mozilla's website, Events are usually triggered by "external" sources like Buttons, they can also be triggered programmatically, such as by calling the HTMLElement.click() method of an element. or by defining the event, then sending it to a specified target using EventTarget.dispatchEvent().

我认为 click 是一个简单的事件,可以通过编程方式触发,但对于< input type = file ..> 来说,是 change 事件.>更为复杂,因为它需要选择一个文件,转换为博客,更新 files 属性等.因此,可能由于这个原因,我不能简单地调用 imageElementNE.change().

I suppose that click is a simple Event and can be triggered programatically but change Event for <input type=file..> is more complicated as it requires selecting a file, converting into a blog, updating files property etc. So probably for this reason, I cannot just simply call imageElementNE.change().

所以我想到了使用 dispatchEvent ,它似乎可以工作

So I thought of using dispatchEvent and it seem to work

1)我明确创建了一个事件.我想 Event 的构造函数有2个参数,第2个是可选的.

1) I created an Event explicitly. I suppose Event's constructor takes 2 arguments, 2nd is optional.

来自 https://developer.mozilla.org/zh-CN/docs/Web/API/Event/Event

event = new Event(typeArg, eventInit);

根据文档, typeArg 是表示事件名称的DOMString.换句话说,第一个参数似乎是事件的 type .当我要发送 change 事件时,我需要将其称为 change .

From documentation, typeArg is a DOMString representing the name of the event. In other words, the 1st argument seem to be the type of the event. As I want to send change event, I need to call it change.

对于 eventInit 部分,我在

For the eventInit part, I looked at the definition of change event at https://developer.mozilla.org/en-US/docs/Web/Events/change and picked the values of bubbles and cancelable from there

let fileSelectEvent = new Event("change",{bubbles:true,
    cancelable: false});

这将创建一个 Event ,其外观如下(我必须承认我不太了解它)

This creates an Event which looks as follows (I must confess I don't understand much of it)

 Event {isTrusted: false, type: "change", target: input#question-file-upload.custom-file-input.ng-untouched.ng-pristine.ng-valid, currentTarget: input#question-file-upload.custom-file-input.ng-untouched.ng-pristine.ng-valid, eventPhase: 2, …}bubbles: truecancelBubble: falsecancelable: falsecomposed: falsecurrentTarget: nulldefaultPrevented: falseeventPhase: 0isTrusted: falsepath: (10) [input#question-file-upload.custom-file-input.ng-untouched.ng-pristine.ng-valid, div#file-upload.custom-file, div.form-group, form#new-question-form.practice-question-form.ng-untouched.ng-pristine.ng-invalid, div#form-div.body__div--background, div#root0, body, html, document, Window]returnValue: truesrcElement: input#question-file-upload.custom-file-input.ng-untouched.ng-pristine.ng-validtarget: input#question-file-upload.custom-file-input.ng-untouched.ng-pristine.ng-validtimeStamp: 3759.4000000026426type: "change"__proto__: Event

2)创建 Event 后,我在 imageInputNE 上调用了 dispatchEvent 方法.与 EventTarget.dispatchEvent()相比,我认为这意味着 EventTarget 会触发事件(在我的情况下, imageInputNE 会触发fileSelectEvent .

2) Once the Event was created, I called the dispatchEvent method on imageInputNE. Comparing with EventTarget.dispatchEvent(), I think it means that the EventTarget is triggering the event (in my case imageInputNE is triggering fileSelectEvent.

imageInputNE.dispatchEvent(fileSelectEvent);

通过的整个规格是

  fit('should keep track of image counter when an image is loaded', () => {
    let newPracticeQuestionComponent = component;
    expect(newPracticeQuestionComponent.currentImageAttachmentCount).toBe(0);
    let imageInputDE = fixture.debugElement.query(By.css("#question-file-upload"));
    expect(imageInputDE).toBeTruthy();
    spyOn(newPracticeQuestionComponent,'handleFileSelect');/*.and.callThrough();/*.and.callFake((event)=>{
      console.log("fake handleFileSelect called with event",event);
    });*/
    /*
    nativeElemenet hasn'nt got any type. As this program will run in a browser, we can
    typecast it to HTMLElement so that we can access prperties and methods of the
    corresponding nativeElement

     The HTMLElement interface represents any HTML element. Some elements directly
     implement this interface, while others implement it via an interface that inherits it.
     */
    let imageInputNE = imageInputDE.nativeElement ;
    console.log("input element is ",imageInputNE);
    console.log("debug element is ",imageInputDE);
    //imageInputNE.click();
    let fileSelectEvent = new Event("change",{bubbles:true,
    cancelable: false});

    console.log("created event ",fileSelectEvent);
    imageInputNE.dispatchEvent(fileSelectEvent);

    expect(newPracticeQuestionComponent.handleFileSelect).toHaveBeenCalled();


  });

以上可能不是最好的解决方案,因为我无法在 input 字段中处理 files ,但这是我能想到的最好的方法!

The above might not be the best solution as I can't manipuate files in the input field but this is the best I could come up with!

这篇关于如何从Angular规范触发输入onchange的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆