角度和角度输入[type =" file"]的Jasmine单元测试更改事件 [英] Angular & Jasmine Unit Test change event for input[type="file"]

查看:75
本文介绍了角度和角度输入[type =" file"]的Jasmine单元测试更改事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试100%的测试覆盖率,但我似乎无法测试这个onUploadFile函数中的内容。

I am trying to go for 100% test coverage, but i can't seem to test the stuff inside this onUploadFile function.

```html template

```html template

<input type="file" formControlName="theUpload" id="upload" (change)="onUploadFile($event, i, true)">

```filing.ts file

```filing.ts file

onUploadFile(evt: Event, index: number, isReq: boolean = false): void {
  const reader = new FileReader();
  const target = <HTMLInputElement>evt.target;

  if (target.files && target.files.length) {
    const file = target.files[0];
    reader.readAsDataURL(file);
    reader.onload = () => {
      this.getUploadFormGroup(index, isReq).patchValue({
        filename: file.name,
        filetype: file.type,
        value: reader.result.split(',')[1],
        dateUploaded: new Date()
      });

      console.log(
        `getUploadFormArray (${isReq ? 'required' : 'other'} forms)`,
        this.getUploadFormArray(isReq)
      );
    };
  }
}

```filing.spec.ts file

```filing.spec.ts file

it('should call onUploadFile when input is changed for required files', () => {
  spyOn(component, 'onUploadFile').and.callThrough();

  const fakeChangeEvent = new Event('change');

  const targ = <HTMLInputElement>de.nativeElement.querySelector('input#upload');
  targ.dispatchEvent(fakeChangeEvent);

  fixture.whenStable().then(() => {
    expect(component.onUploadFile).toHaveBeenCalledWith(fakeChangeEvent, 0, true);
    expect(targ.files.length).toBeGreaterThan(0); //  this is always zero because i can't add to targ.files (readonly FileList)
  });
});

我愿意嘲笑任何可以嘲笑的东西,但有人可以告诉我如何测试 console.log function(要求我在 target.files 数组中至少有一项?

I am open to mocking whatever can be mocked, but can someone please show me how I might test the console.log function (requiring that i have at least one item in the target.files array?

推荐答案

让我们按照划分和征服规则 - 因为单元测试的目的是测试组件逻辑的各个部分另外,我会略微更改组件逻辑,以便更容易进行单元测试。

Let's follow the divide and conquer rule - since the aim of Unit Test is to test the parts of component logic separately, I would slightly change the component logic in order to make it easier to Unit Test.

您正在为 onload设置匿名回调函数在你的 onUploadFile 方法中,所以没有办法对它进行spyOn。作为权衡 - 你可以重构回调方法:

You're setting the anonymous callback function for onload inside your onUploadFile method, so there is no way to spyOn it. As a trade off - you can refactor out the callback method:

export class TestComponent {
  ...
  getLoadCallback(fg: FormGroup, file: File, reader: FileReader): () => void {
    return () => {
      fg.patchValue({
        filename: file.name,
        filetype: file.type,
        value: reader.result.split(',')[1],
        dateUploaded: new Date()
      });

      // do some other stuff here
    };
  }

  onUploadFile(evt: Event, index: number, isReq: boolean = false): void {
    const reader = new FileReader();
    const target = <HTMLInputElement>evt.target;

    if (target.files && target.files.length) {
      const file = target.files[0];
      reader.readAsDataURL(file);
      const fg = this.getUploadFormGroup(index, isReq);
      reader.onload = this.getLoadCallback(fg, file, reader);
    }
  }
  ...
}

所以,现在我们可以创建至少三个单元测试:一个用于在输入事件上触发 onUploadFile (您的现有测试对此有利),另一个用于测试 getLoadCallback 方法,最后 - 对于 onUploadFile 方法:

So, now we can create at least three Unit Tests: one for triggering onUploadFile on input event (your existing test is good for this), another one for testing getLoadCallback method and lastly - for onUploadFile method:

  it('getLoadCallback', () => {
    const mockValue = ['a', 'b'];
    const result = jasmine.createSpyObj('result', ['split']);
    result.split.and.callFake(() => mockValue);
    const mockReader = { result } as FileReader;
    const mockFormGroup: FormGroup = jasmine.createSpyObj('FormGroup', ['patchValue']);
    const mockFile = new File([''], 'filename', { type: 'text/html' });
    const callback: () => void = component.getLoadCallback(mockFormGroup, mockFile, mockReader);

    callback();

    const obj = {
      filename: mockFile.name,
      filetype: mockFile.type,
      value: mockValue[1],
      dateUploaded: new Date()
    }
    expect(mockFormGroup.patchValue).toHaveBeenCalledWith(obj);
  });

  it('onUploadFile', () => {
    const mockIndex = 1;
    const mockIsReq = false;
    const mockFile = new File([''], 'filename', { type: 'text/html' });
    const mockFormGroup = new FormGroup({});
    const mockEvt = { target: { files: [mockFile] } };
    const mockReader: FileReader = jasmine.createSpyObj('FileReader', ['readAsDataURL', 'onload']);
    spyOn(window as any, 'FileReader').and.returnValue(mockReader);
    spyOn(component, 'getUploadFormGroup').and.returnValue(mockFormGroup);
    spyOn(component, 'getLoadCallback').and.callThrough();

    component.onUploadFile(mockEvt as any, mockIndex, mockIsReq);

    expect((window as any).FileReader).toHaveBeenCalled();
    expect(mockReader.readAsDataURL).toHaveBeenCalledWith(mockFile);
    expect(component.getUploadFormGroup).toHaveBeenCalledWith(mockIndex, mockIsReq);
    expect(component.getLoadCallback).toHaveBeenCalledWith(mockFormGroup, mockFile, mockReader);
  });

当然,您可以更改模拟值并创建更多单元测试......

Of course you can change mock values and create more unit tests...

这篇关于角度和角度输入[type =&quot; file&quot;]的Jasmine单元测试更改事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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