programing

Angular2 - 데바운스 시간이 있는 테스트 호출

padding 2023. 6. 22. 21:35
반응형

Angular2 - 데바운스 시간이 있는 테스트 호출

다음을 사용하여 변경 내용을 검색하는 양식 컨트롤을 사용하고 있습니다.valueChanges그리고.debounceTime나는 스파이 활동을 하는 시험을 쓰고 있습니다.itemService그것을 확인하기 위해update메서드를 호출하는 중입니다.만약 내가 그것을 제거한다면.debounceTime폼 컨트롤에서 테스트는 정상적으로 작동합니다.

구성 요소의 양식 컨트롤입니다.

this.itemControl.valueChanges.debounceTime(300).subscribe(response => {
   this.itemService.update(response);
});

여기 테스트가 있습니다.

it('should do stuff',
    inject([ItemService], (itemService) => {
      return new Promise((res, rej) =>{
        spyOn(itemService, 'update');
        let item = {
            test: 'test'
        };
        fixture.whenStable().then(() => {
          let itemControl = new FormControl('test');
          fixture.componentInstance.itemControl = itemControl;
          fixture.autoDetectChanges();

          fixture.componentInstance.saveItem(item);
          expect(itemService.update).toHaveBeenCalled();

})}));

다음은 구성 요소의 saveItem 함수입니다.

saveItem(item): void {
    this.itemControl.setValue(item);
}

말했듯이, 만약 내가 제거한다면,debounceTime폼 컨트롤에서 테스트는 정상적으로 실행되지만, 저는 그렇게 할 수 없습니다.추가해봤습니다.tick()사전에 전화를 보다expect전화를 걸었지만 이 오류가 발생했습니다.

Unhandled Promise rejection: The code should be running in the fakeAsync zone to call this function ; Zone: ProxyZone ; Task: Promise.then ; Value: Error: The code should be running in the fakeAsync zone to call this function Error: The code should be running in the fakeAsync zone to call this function

가짜 Async()와 체크 표시()를 사용해야 합니다.문제의 테스트 코드를 기준으로 내 쪽에서 성공적으로 실행된 아래 코드(.spec.ts 파일)를 확인하십시오.

아래 코드 설명:
fakeAsync()그리고.tick()항상 함께 사용해야 합니다.사용할 수 있습니다.async()/fixtureInstance.whenStable()함께, 그러나 프로그래머의 관점에서 그것은 덜 "예측 가능"합니다.를 사용하는 것이 좋습니다.fakeAsync()/tick()가능할 때마다다음만 사용해야 합니다.async()/fixtureInstance.whenStable()테스트 코드가 XHR 호출을 할 때(Http 요청 테스트라고도 함).

사용하는 것이 가장 좋습니다.fakeAsync()/tick()테스트 코드에서 비동기 코드가 작동하는 방식을 수동으로 제어할 수 있기 때문에 가능합니다.

아래 코드(.spec.ts 파일)에서 확인할 수 있습니다.메서드 매개 변수를 사용하여 눈금 메서드를 호출하는 것이 매우 중요합니다.300,tick(300)당신이 설정한 데바운스 값이300데바운스 값을 다음과 같이 가정할 경우500그러면 당신의 틱 값은500이 상황에서 통과하기를 원하는 경우 테스트 코드에 있습니다.

설정하면 다음과 같이 표시됩니다.tick(299)당신의 시험은 실패할 것입니다, 하지만 당신이 당신의 데바운스 값을 설정했기 때문에 그것은 맞습니다.300이것은 당신이 사용하는 힘을 보여줍니다.fakeAsync()/tick()사용자는 코드 타이밍을 제어합니다(사용자는 시간의 마스터입니다).fakeAsync()/tick()).


// component.sandbox.spec.ts
import { async, TestBed, fakeAsync, tick, inject } from "@angular/core/testing";
import { ReactiveFormsModule } from "@angular/forms";
import { SandboxComponent } from "./component.sandbox";
import { ItemService } from "../../Providers";
import "rxjs/add/operator/debounceTime";

describe("testFormControl", () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [ReactiveFormsModule],
      declarations: [SandboxComponent],
      providers: [ItemService],
    }).compileComponents();
  }));

  // The test you had questions about :)
  it("(fakeAsync usage) Should hit the ItemService instance's 'update' method once", fakeAsync(inject([ItemService], (itemService: ItemService) => {
    spyOn(itemService, "update");
    let fixture = TestBed.createComponent(SandboxComponent);
    fixture.detectChanges(); // It is best practices to call this after creating the component b/c we want to have a baseline rendered component (with ng2 change detection triggered) after we create the component and trigger all of its lifecycle events of which may cause the need for change detection to occur, in the case attempted template data bounding occurs.

    let componentUnderTest = fixture.componentInstance;

    componentUnderTest.saveItem("someValueIWantToSaveHEHEHE");

    tick(300); // avoliva :)

    expect(itemService.update).toHaveBeenCalled();

  })));

});

// component.sandbox.ts
import { Component, OnInit } from "@angular/core";
import { FormGroup, FormControl } from "@angular/forms";
import { ItemService } from "../../Providers";

@Component({
  template: `
    <form [formGroup]="formGroupInstance">
      <input formControlName="testFormControl" />
      <button type="submit">Submit</button>
      <button type="button" (click)="saveItem(formGroupInstance.controls['testFormControl'].value)">saveItem(...)</button>
    </form>
  `,
  styleUrls: ["component.sandbox.scss"],
})
export class SandboxComponent extends OnInit {
  public formGroupInstance: FormGroup;
  public testFormControlInstance: FormControl;

  constructor(private itemService: ItemService) {
    super();

    this.testFormControlInstance = new FormControl();

    this.formGroupInstance = new FormGroup(
      {
        testFormControl: this.testFormControlInstance,
      },
    );
  }

  public ngOnInit() {
    this.testFormControlInstance.valueChanges
      .debounceTime(300) // avoliva
      .subscribe((formControlInstanceValue: {}) => {
        this.itemService.update(formControlInstanceValue);
      });
  }

  public saveItem(item: any) {
    this.testFormControlInstance.setValue(item);
  }

}

// ../../Provider/index.ts
export class ItemService {
  public update(formControlInstanceValue: any) {
    // Makes http request to api to update item
    console.log(`HEY PROGRAMMER, YEAH YOU! :P \n => http request could have been made
    here to update an 'item' in the database.`);
  }
}

언급URL : https://stackoverflow.com/questions/41641995/angular2-testing-call-with-a-debouncetime

반응형