programing

이벤트 방법 이벤트 방법 이벤트 방법

testmans 2023. 10. 2. 11:16
반응형

이벤트 방법

보기에서 <input type='file'>.

내 Angular의 컨트롤러 부분에서JS app 파일은 입력의 변경 이벤트 내에서 다음과 같이 처리됩니다.

//bind the change event of the file input and process the selected file
inputElement.on("change", function (evt) {
    var fileList = evt.target.files;
    var selectedFile = fileList[0];
    if (selectedFile.size > 500000) {
        alert('File too big!');
    // ...

evt.target.files사용자가 선택한 파일 대신 모의 데이터를 내 유닛 테스트에 포함하는 것입니다.나는 내가 그 일을 이해할 수 없다는 것을 깨달았습니다.FileList그리고.File브라우저가 작업 중인 개체에 해당하는 개체를 나 자신이 직접 개체는 다음과 같습니다.는 입력의 파일 했습니다.files속성 및 수동으로 변경 이벤트를 트리거합니다.

describe('document upload:', function () {
    var input;

    beforeEach(function () {
        input = angular.element("<input type='file' id='file' accept='image/*'>");
        spyOn(document, 'getElementById').andReturn(input);
        createController();
    });

    it('should check file size of the selected file', function () {
        var file = {
            name: "test.png",
            size: 500001,
            type: "image/png"
        };

        var fileList = {
            0: file,
            length: 1,
            item: function (index) { return file; }
        };

        input.files = fileList; // assign the mock files to the input element 
        input.triggerHandler("change"); // trigger the change event

        expect(window.alert).toHaveBeenCalledWith('File too big!');
    });

안타깝게도 이로 인해 컨트롤러에서 다음과 같은 오류가 발생하는데, 이는 파일이 입력 요소에 전혀 할당되지 않았기 때문에 이 시도가 실패했음을 보여줍니다.

TypeError: 'undefined'가 개체가 아닙니다('evt.target'을(를) 평가합니다.파일')

나는 그 .input.files속성은 보안상의 이유로 읽기 전용입니다.그래서 저는 파일 속성을 제공할 수 있는 맞춤형 변경사항을 발송하면서 또 다른 접근 방식을 시작했지만, 여전히 성공하지 못했습니다.

간단히 말해서, 이 테스트 사례에 접근하는 방법에 대한 실용적인 해결책이나 모범 사례를 배우고 싶습니다.

업데이트: @PeteBD 덕분에,

버전 1를 angularjs 는합니다 1.2.22 로, jqLite 으로 하는 것을 합니다.triggerHandler(). 참조: d262378b


jqLite만 사용하고 있다면,

triggerHandler()더미 이벤트 개체를 핸들러에 전달하므로 결코 작동하지 않습니다.

더미 이벤트 개체는 다음과 같습니다(jqLite.js#L962에서 복사).

{
  preventDefault: noop,
  stopPropagation: noop
}

target소유물.

jQuery를 사용하는 경우,

다음과 같은 사용자 지정 이벤트 개체로 이벤트를 트리거할 수 있습니다.

input.triggerHandler({
  type: 'change',
  target: {
    files: fileList
  }
});

.evt.target.files이 될 fileList예상하신 대로

도움이 되길 바랍니다.

Angular를 JS를 다시 생각해 봅시다.DOM must be handled in a directive

에서 DOM 를 는 안 .element.on('change', .. 의 목적으로 할 수 있습니다컨트롤러에서는 DOM이 아니라 데이터와 대화합니다.

그래서 그것들은onchange다와 .

<input type="file" name='file' ng-change="fileChanged()" /> <br/>

ng-change다에서는 잘 .type="file"이 이것과 저는 향후 버전이 이것과 함께 작동하는지 확신할 수 없습니다.우리는 여전히 같은 방법을 적용할 수 있습니다.

<input type="file" 
  onchange="angular.element(this).scope().fileChanged(this.files)" />

컨트롤러에서는 단순히 방법을 정의합니다.

$scope.fileChanged = function(files) {
  return files.0.length < 500000;
};

이제 모든 것이 정상적인 컨트롤러 테스트일 뿐입니다.더 이상 상대하지 않음angular.element,$compile,triggers, 등! :)

describe(‘MyCtrl’, function() {
  it('does check files', inject(
    function($rootScope, $controller) {
      scope = $rootScope.new();
      ctrl = $controller(‘UploadCtrl’, {‘$scope’: scope});

      var files = { 0: {name:'foo', size: 500001} };
      expect(scope.fileChanged(files)).toBe(true);
    }
  ));
});

http://plnkr.co/edit/1J7ETus0etBLO18FQDhK?p=preview

다음은 angular2+를 사용한 입력 파일/이미지 사양 예입니다.

it('should call showError on toastService Api on call of onSaveOfImage() method', () => {

    spyOn(component.commonFacade.fileIOApi, 'uploadFile');
    let file = new File([new ArrayBuffer(2e+5)], 'test-file.jpg', { lastModified: null, type: 'image/jpeg' });
    let fileInput={ files: [file] };
    component['onSaveOfImage'](fileInput,"",null,"","");
    expect(component.commonFacade.fileIOApi.uploadFile).toHaveBeenCalledTimes(1);
    expect(component.uploadedFileData).toBeUndefined();
    expect(component.commonFacade.employeeApi.toastService.showError).toHaveBeenCalledTimes(1);
  })

@Adrita Sharma가 다른 게시물에서 제안한 것처럼, 유효한 값을 조롱하는 쉬운 방법.event.target.filesDataTransfer 개체를 사용하고 있습니다.이를 통해 FileList 개체를 만들 수 있습니다.

다음 샘플은 jasmine 4.5에서 작동합니다.

it('should simulate file selection', () => {
        const file = new File(['file contents'], 'file.txt', { type: 'text/plain' });

        const dataTransfer = new DataTransfer();
        dataTransfer.items.add(file);

        const inputElement = fixture.debugElement.nativeElement.querySelector('input');

        // That's the trick
        inputElement.files = dataTransfer.files;

        // now event.target.files must have a file

        inputElement.dispatchEvent(new Event('change'));
        
        {...}

});

파일 변경 처리기는 컨트롤러에 직접 있는 기능일 수 있습니다.HTML 또는 지시어에서 해당 함수를 변경 이벤트에 바인딩할 수 있습니다.이렇게 하면 이벤트가 발생할 염려 없이 핸들러 기능을 직접 호출할 수 있습니다.이 egghead.io 비디오에서는 다음과 같은 몇 가지 방법을 다룹니다. https://egghead.io/lessons/angularjs-file-uploads

Angular로 자신의 파일 업로더를 굴릴 때 걱정해야 할 것들이 많기 때문에, 저는 그것을 처리하는 기존의 라이브러리들 중 하나를 사용할 것입니다. 예를 들어 Angular-file-uppload.

언급URL : https://stackoverflow.com/questions/25097738/how-to-provide-mock-files-to-change-event-of-input-type-file-for-unit-testin

반응형