【问题标题】:Angular Unit testing ControlValueAccessor with ngForAngular 单元测试 ControlValueAccessor 与 ngFor
【发布时间】:2021-09-29 01:25:12
【问题描述】:

在 ControleValueAccessor 内部使用时如何测试 ngFor 元素。

@Component({
  selector: 'checkbox-group',
  templateUrl: `
<h3 class="tt">s</h3>
<ng-container *ngFor="let item of _model;let i = index" >  <h3>s</h3>
  <div>
      <input type="checkbox" id="c{{i}}"/>
  </div>
</ng-container>

`,
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => CheckboxGroupComponent),
      multi: true
    }
  ]
})

export class CheckboxGroupComponent implements ControlValueAccessor {
  constructor(private ref: ChangeDetectorRef) {
    ref.detach();
  }
  writeValue(value: any): void {
    this._model = value;
    if(value != null) { this.ref.detectChanges();
  }
}

并从父 settings.html 导入此控件值访问器:

<div>
  <checkbox-group [(ngModel)]="selectedItems"></checkbox-group>
</div>

现在当我想测试它时,它只有一个子元素。并且只知道标签是第一个和最后一个子元素

setting.spec.ts:

TestBed.configureTestingModule({
      declarations: [ SettingsPage, CheckboxGroupComponent ],
      imports: [IonicModule.forRoot()],
      providers: [
        {
          provide: NG_VALUE_ACCESSOR,
          useExisting: forwardRef(() => CheckboxGroupComponent),
          multi: true
        }
        // other providers
      ],
      schemas: [ NO_ERRORS_SCHEMA ]
}).compileComponents();

it('should get checkBoxGroup Childs', fakeAsync(() => {  
    let customComponent = fixture.nativeElement.querySelector('checkbox-group');
    component.selectedItems = [true,true,true];
    fixture.detectChanges();
    fixture.whenStable().then(() => {
      customComponent.NgModule=[true,false,true];
      fixture.detectChanges();
      debugger;        
    }); 
}))

在 customComponent 上调试:

【问题讨论】:

    标签: angular jestjs jasmine angular-test angular2-changedetection


    【解决方案1】:

    我不完全确定您要做什么,但试试这个:

    注意标明的cmets!!

    import { By } from '@angular/platform-browser';
    ....
    TestBed.configureTestingModule({
          declarations: [ SettingsPage, CheckboxGroupComponent ],
          imports: [IonicModule.forRoot()],
          providers: [
          /* !! Get rid of these lines because CheckboxGroupComponent
             is already doing the providing !!
            {
              provide: NG_VALUE_ACCESSOR,
              useExisting: forwardRef(() => CheckboxGroupComponent),
              multi: true
            } */
            // other providers
          ],
          schemas: [ NO_ERRORS_SCHEMA ]
    }).compileComponents();
    
    it('should get checkBoxGroup Childs', fakeAsync(() => {  
        component.selectedItems = [true,true,true];
        fixture.detectChanges();
        // !! We can queryAll of the CSS elements and expect the length to be 3
        let customComponents = fixture.debugElement.queryAll(By.css('checkbox-group'));
        expect(customComponents.length).toBe(3);
    }))
    

    !!编辑!!

    <h3 class="tt">s</h3> // <-- this is the h3 you're seeing
    <h1>Model's value: </h1>
    <pre>{{ _model | json }}</pre>
    <ng-container *ngFor="let item of _model;let i = index" >  <h3>s</h3> // You want to see <h3>s</h3>
      <div>
          <input type="checkbox" id="c{{i}}"/>
      </div>
    </ng-container>
    

    所以你是说你只看到带有 tt 类的 h3 而不是里面带有 s 的 h3?

    我添加了一个h1 和一个pre 标记来显示_model 的值。查看它的值是什么,并确保它不是一个空数组。

    【讨论】:

    • 谢谢,我会试试这个,ControleValueAccessor 有一个单独的 h1 标签和由 ngfor 从 _mode 添加的动态元素复选框。我可以得到 h1 元素,但似乎动态元素没有加载或没有检测到变化。
    • 它不起作用 ;( ,customComponents 只有一个 h1 元素
    • 查看我的编辑,希望它可以帮助您调试问题。
    • 我发现只有 ngfor 没有渲染,我也会检查一下。我必须制作一个 stackbliz。谢谢?
    猜你喜欢
    • 2016-05-05
    • 2020-07-07
    • 2017-11-19
    • 1970-01-01
    • 2020-08-08
    • 2017-04-04
    • 2019-03-24
    • 2016-12-29
    • 2021-02-12
    相关资源
    最近更新 更多