簡體   English   中英

Angular 中沒有 TestBed 和組件的單元測試指令

[英]Unit Tesing directives in Angular without TestBed & Component

我確實為一個指令編寫了一個單元測試並且它可以工作,但我想問一下我是否可以在沒有組件和 TestBed 的情況下測試它。 我在這里可以改變什么或我可以改進什么? 創建TestComponent的想法和TestBed的想法是什么

這是指令的代碼。

@Directive({
  selector: '[ngModel][endOfSeasonValidation]',
  providers: [
    {
      provide: NG_VALIDATORS,
      useExisting: forwardRef(() => EndOfSeasonValidationDirective),
      multi: true,
    },
  ],
})
export class EndOfSeasonValidationDirective extends AbstractValidatorDirective {
  @Input('beginDate')
  public beginDate: Date | null;

  @Input('startOfSeason')
  public startOfSeason: number | null;

  public validate(control: AbstractControl): ValidationErrors | null {
    const endOfSeason = control.value;

    if (!endOfSeason || !this.startOfSeason || !this.beginDate) {
      return null;
    }

    if (
      endOfSeason === this.startOfSeason ||
      endOfSeason + (endOfSeason < this.startOfSeason ? 12 : 0) - this.startOfSeason === 11
    ) {
      return { isInvalid: true };
    }

    return null;
  }
}

這是單元測試的代碼

@Component({
  template: `
    <form>
      <select
        endOfSeasonValidation
        [ngModel]="endOfSeason"
        name="endOfSeason"
        [beginDate]="beginDate"
        [startOfSeason]="startOfSeason"
      ></select>
    </form>
  `,
})
class EndOfSeasonValidationTestComponent {
  public beginDate = new Date('2020-01-16');
  public startOfSeason: number | null;
  public endOfSeason: number | null;
  @ViewChild(NgForm, { static: true })
  public form: NgForm;
}
describe('EndOfSeasonValidationDirective', () => {
  let fixture: ComponentFixture<EndOfSeasonValidationTestComponent>;
  let form: NgForm;
  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [
        EndOfSeasonValidationTestComponent,
        EndOfSeasonValidationDirective,
        DateAccessorPluginDirective,
        SelectAccessorDirective,
      ],
      imports: [FormsModule],
    }).compileComponents();
    fixture = TestBed.createComponent(EndOfSeasonValidationTestComponent);
    fixture.detectChanges();
    await fixture.whenStable();
    form = fixture.componentInstance.form;
  });
  it('should not validate if beginDate or startOfSeason or endOfSeason are not given', async () => {
    fixture.componentInstance.beginDate = new Date('2020-01-01');
    fixture.detectChanges();
    await fixture.whenStable();
    expect(form.valid).toBeTruthy();
    expect(form.errors).toBeFalsy();
  });
  it('should validate if startOfSeason and endOfSeason are equal', async () => {
    fixture.componentInstance.beginDate = new Date('2020-12-02');
    fixture.componentInstance.startOfSeason = 2;
    fixture.componentInstance.endOfSeason = 2;
    fixture.detectChanges();
    await fixture.whenStable();
    expect(fixture.componentInstance.form.invalid).toBeTruthy();
  });
});

根據 angular docs測試Directive正確方法 - 是使用某些組件(是否使用 TestComponent)。
回答您的問題:

  1. 您可以簡單地創建實例來測試您的指令,直到它沒有 DI 依賴項。

const dir = new EndOfSeasonValidationDirective();
... some changes with inputs
expect(dir.validate()).toEqual({isInvalid: true})

但是在更真實的環境中測試它的更好方法 - 與某些組件配對使用。 因此,創建 TestComponent 的想法是為您的單元測試提供更真實的環境(運行引擎蓋下的所有角內齒輪)。

  1. TestBed是一個輔助工具,用於解決 angular DI 依賴項並創建測試模塊。
  2. 我認為你的測試很好,但你可以通過將它覆蓋到 100% 來改進它。 應該測試所有 case 和If語句。

UPD完全你應該涵蓋這些情況:

  1. 如果未提供 endOfSeason,則不應驗證

  2. 如果未提供 startOfSeason,則不應驗證

  3. 如果未提供 beginDate 則不應驗證

  4. 應該驗證 startOfSeason 和 endOfSeason 是否相等

  5. 應該驗證 if (我不知道這個表達式在商業詞匯中是什么意思) endOfSeason + (endOfSeason < this.startOfSeason ? 12 : 0) - this.startOfSeason === 11

編寫這些測試后,該指令的覆蓋率將是 100%,所有情況都將被測試。 例如,您可以在WebstormIntellij IDEA通過按Run with Coverage按鈕運行它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM