簡體   English   中英

帶茉莉花測試的Angular 2 +,[ngClass] =“ methodName(configObj)”問題

[英]Angular 2+ w/Jasmine Testing: [ngClass]=”methodName(configObj)” issue

我已經閱讀了整個angular.io測試文檔,在Google上搜索了關鍵字,並在此處使用了高級搜索,但沒有找到適合我的情況的任何內容。 我是單元測試的新手,所以也許我還沒有術語。 如果重復,請給我指出正確的方向。

預示:我的問題是

A.)Angel /茉莉花能夠測試模板方法調用中的動態參數。

要不然...

B.)您將如何在每個Fixture.detectChanges()期間模擬將參數傳遞給方法?

這是情況和失敗的代碼...

<generic-element 
  *ngFor=”let recordObj of recordsArray” 
  [ngClass]=”doSetClasses(recordObj)”
></generic-element>

總而言之,我有一個組件模板,其中元素動態地獲取通過方法分配的類。 此方法獲取一個對象(通過ngFor指令從列表中提取),並檢查該對象以確定應返回模板的類名稱。 對於真正冗長的賦值,我更喜歡通過方法賦值,因為我嘗試將邏輯盡可能地保存在打字稿文件和HTML中的結構中……至少要盡可能。

我的非常簡單的單元測試失敗了,因為“無法讀取未定義的屬性'id'”(在這種情況下,未定義是recordObj從模板傳遞到doSetClasses()方法中。之所以將其隔離,因為如果我只是覆蓋並剝離測試環境中所有通過的doSetClasses方法的內容都通過了,例如:

beforeEach {
   ...
   component.doSetClasses = function() { return; } as any;
}

現在,如果我按原樣保留doSetClasses方法,我會注意到,如果我不調用Fixture.detectChanges(),它也會通過。 所以我的問題似乎是:在角度變化檢測/消化周期中,從模板調用的測試方法也從模板中包含了參數。

我的問題是

A.)Angel /茉莉花能夠測試模板方法調用中的動態參數。

要不然...

B.)在測試環境中的每個夾具.detectChanges()期間,如何模擬將參數傳遞給方法?

同樣,如果這是重復的,請指出正確的方向。

在此先感謝您的幫助,建議和指導。 非常感激。

幾天沒有答案,評論或問題,看來沒有指導意見要提交。 因此,對於以后可能會遇到類似問題的任何人,我得出的結論是:

  1. 我不認為有一種方法可以有機地[ngClass] =“ doSetClasses(recordObj)”,即每個摘要周期,從* ngFor動態獲取其參數,並在單元測試中工作,因此我不得不模擬它。
  2. 在測試環境中,創建doSetClasses()方法的副本。
  3. 然后剝離原始doSetClasses()方法的內容,以便仍然可以被代碼/其他測試調用,但最終卻什么也沒做。
  4. 在測試doSetClasses本身的實際使用時,請改用副本並模擬方案。

我目前無法訪問我的代碼,但這是速記:

beforeEach() {
  //Create a copy to use in controlled scenarios
  const doSetClassesCopy = doSetClasses;
  //Then strip out contents so it can be called but does not error during testing
  doSetClasses = function() { return; } as any;
}

...
(The Test)
  //Now mock it's performance with params from template's *ngFor directive
  const simulatedParamsFromTemplate = { value: 'whatever' } as recordObj;
  const outcome = doSetClassesCopy(simulatedParamsFromTemplate);
  expect(outcome).toBe('Whatever I expect.');

如果有人有更好的解決方案或建議,我將有興趣聽。 謝謝。

我今天也遇到了類似的問題。 調用ngClass fixture.detectChanges()似乎會觸發ngClass提到的函數的調用。

我想調用validateField ,它將把Bootstrap的類分配給控件

的HTML

<form class="form-inline" [formGroup]="loginForm" (ngSubmit)="signInUser()" novalidate>
            <input type="text" id="username" class="form-control" placeholder="username" formControlName="userName" [ngClass]="validateField('userName')" required>
            <input type="password" id="password" class="form-control" placeholder="password" formControlName="password" [ngClass]="validateField('password')" required>
...

.tsvalidateField函數是

/*

  This function will eventually return object of type depending on whether the field is valid or not, set Bootstrap's css
   {
      'is-invalid': true or false, // if fieldvalid returns false i.e. field is not valid then we want has-error css. So set it to true (opp. of fieldValid)
      'is-valid': true or false //if fieldvalid returns true i.e. field is valid then we want has-success css. So set it to true (value of fieldValid)
   }
   */
  validateField(field:string){
   // console.log("validating field: " +field)
    return this.helper.validateField(this.loginForm,field);
  }

我的spec

fit('it should validate that the data in username and password field has correct format',()=>{
    let navComponent = component;
    let helperService = TestBed.get(HelperService);
    spyOn(helperService,'validateField');
    let formControls = navComponent.loginForm.controls;
    let email = 'test@test.com';
    let password = 'testpassword';
    formControls['userName'].setValue(email);
    fixture.detectChanges(); //<-- THIS SEEM TO TRIGGER THE CALLING OF VALIDATION FUNCTION
    expect(helperService.validateField).toHaveBeenCalledWith(navComponent.loginForm,'userName');
    formControls['password'].setValue(password);
    fixture.detectChanges();//<-- THIS SEEM TO TRIGGER THE CALLING OF VALIDATION FUNCTION
    expect(helperService.validateField).toHaveBeenCalledWith(navComponent.loginForm,'password');

  });

暫無
暫無

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

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