【问题标题】:How to write the unit testing for the file upload method in the Angular 7 (or 2+)如何在 Angular 7(或 2+)中为文件上传方法编写单元测试
【发布时间】:2019-08-16 18:34:42
【问题描述】:

我正在尝试为 Angular 7 中的文件上传方法编写单元测试。在测试窗口中出现以下错误。我是角度单元测试的新手。有人可以帮忙,如何添加模拟文件以获得完整的代码覆盖率?

TypeError:无法设置未定义的属性“值”

这是我的单元测试代码(规范文件),

describe('ImportComponent', () => {
    let component: ImportComponent;
    let fixture: ComponentFixture<ImportComponent>;
    let element;

    beforeEach(
        async(() => {
            TestBed.configureTestingModule({
                imports: [ HttpClientModule, RouterTestingModule ],
                declarations: [ ImportComponent ]
            }).compileComponents();
        })
    );

    beforeEach(() => {
        fixture = TestBed.createComponent(ImportComponent);
        component = fixture.componentInstance;
        element = fixture.nativeElement;
        fixture.detectChanges();
    });

    it('should create', () => {
        expect(component).toBeTruthy();
    });

    it('should upload the file', () => {
        component.importFile();
        const inputEl = element.querySelector('#postal_file');
        const fileList = { 0: { name: 'foo', size: 500001 } };
        inputEl.value = {
            target: {
                files: fileList
            }
        };
        inputEl.dispatchEvent(new Event('change'));     
    });
});

组件中的方法

importFile() {
        const inputEl: HTMLInputElement = this.el.nativeElement.querySelector('#postal_file');
        const fileCount: number = inputEl.files.length;
        const formData = new FormData();
        if (fileCount > 0) {
            formData.append(this.postalFileName, inputEl.files.item(0));
            this.postalService.importPostalCodes(formData).subscribe((data) => {
                this.result = data;
            });
        }
    }

和 HTML,

<div class="file-import">
        <form action="" method="post" encType="multipart/form-data">
            <label for="postal_file">Choose File</label>
            <input type="file" name="postal_file" id="postal_file">
            <button type="button" (click)="importFile()">Import</button>
        </form>
    </div>

单元测试没有覆盖下图所示的所有代码,请帮忙,如何获得100%的代码覆盖率。

Code coverage image

【问题讨论】:

    标签: angular karma-jasmine angular-test


    【解决方案1】:

    对于上述部分的 100% 代码覆盖率,我在下面添加了 2 个测试用例。这对我有用。

    it('should upload the file - checkFileExist = true', () => {
        spyOn(component, 'checkFileExist').and.returnValue(true);
        spyOn(postalService,'importPostalCodes').and.callThrough();
        component.importFile();
        expect(postalService.importPostalCodes).toHaveBeenCalled();
    });
    
    it('should upload the file - checkFileExist = false', () => {
        spyOn(component, 'checkFileExist').and.returnValue(false);
        spyOn(postalService,'importPostalCodes').and.callThrough();
        component.importFile();
        expect(postalService.importPostalCodes).toHaveBeenCalledTimes(0);
    });
    

    【讨论】:

      【解决方案2】:

      测试文件上传和检查模型值集的简单方法。

      .html

      <input (change)="onFileSelected()" #fileInput type="file" id="file">
      

      .ts

      uploadedFile : any
      
      onFileSelected() {
        const inputNode: any = document.querySelector('#file');
        this.uploadedFile  = inputNode.files[0];
      }
      

      spec.ts

      it('should detect file input change and set uploadedFile  model', () => {
          const dataTransfer = new DataTransfer()
          dataTransfer.items.add(new File([''], 'test-file.pdf'))
      
          const inputDebugEl  = fixture.debugElement.query(By.css('input[type=file]'));
          inputDebugEl.nativeElement.files = dataTransfer.files;
      
          inputDebugEl.nativeElement.dispatchEvent(new InputEvent('change'));
      
          fixture.detectChanges();
      
          expect(component.uploadedFile).toBeTruthy()
          expect(component.uploadedFile).toBe('test-file.pdf')
          
      });
      
      it('file change event should arrive in handler', () => {
          const element = fixture.nativeElement;
          const input = element.querySelector('#file');
          spyOn(component, 'onFileSelected');
          input.dispatchEvent(new Event('change'));
          fixture.detectChanges();
          expect(component.onFileSelected).toHaveBeenCalled();
      });
      

      【讨论】:

      • 太棒了..!真的你回答值得100个赞..!!
      • 您好@adrita,您的回答对我帮助很大,但是如何传递一个包含有效数据的实际 csv 文件来覆盖主要组件代码中的其他行?
      猜你喜欢
      • 2020-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-06
      • 2021-01-07
      • 1970-01-01
      • 1970-01-01
      • 2015-08-31
      相关资源
      最近更新 更多