Angular 14: 使用Jest测试ngFor

huangapple go评论59阅读模式
英文:

Angular 14: Test a ngFor using Jest

问题

这是我的简单面包屑组件。我想测试属性 *active* 是否存在于 `routerLink` 中。

我想获取 `<a>` HTML 元素,但我总是得到 `null`。我尝试过使用 `compiled.querySelector('a')`,但结果相同。无论我有 1、2 还是 3 个元素,我都想要 `<a>` HTML 元素。

我还想访问 `routerLink` 属性,但如果我使用 `.getAttribute('routerLink')`,我得到一个空值。

我认为这可能与 *生命周期* 有关,因为如果我尝试获取 `<nav>` 元素,我是可以的。

问题出现在我试图访问循环中的元素时。
英文:

This is my simple breadcrumbs component. I want to test if the property active is inside the routerLink.

<nav>
  <ol>
    <ng-container *ngFor="let breadcrumb of breadcrumbs">
      <li
        [ngClass]="{ active: breadcrumb.active }"
        *ngIf="!breadcrumb.disabled"
      >
        <span *ngIf="breadcrumb.active">{{ breadcrumb.text }}</span>

        <a *ngIf="!breadcrumb.active" [routerLink]="breadcrumb.to">{{
          breadcrumb.text
        }}</a>
      </li>
    </ng-container>
  </ol>
</nav

I want to get the <a> HTML element, but I always get null. I have tried with compiled.querySelector('a') but the same occurs. I want the <a> HTML element, no matter if I have 1, 2 o 3 elements.

I also want to access to the routerLink attribute, but if I use .getAttribute('routerLink') I get a null value.

describe('BreadcrumbsComponent', () => {
  let component: BreadcrumbsComponent;
  let fixture: ComponentFixture<BreadcrumbsComponent>;
  let compiled: HTMLElement;

  beforeEach(waitForAsync(() => {
    TestBed.configureTestingModule({
      declarations: [BreadcrumbsComponent],
      imports: [IonicModule.forRoot(), RouterTestingModule],
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(BreadcrumbsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
    compiled = fixture.nativeElement;
  });

  test('should receive breadcrumb prop', async () => {
    component.breadcrumbs = [
      {
        text: 'Test',
        disabled: false,
        to: '/route',
        active: true,
      },
    ];

    await fixture.whenStable();

    const a = fixture.debugElement.nativeElement.querySelector('nav'); // null

    fixture.detectChanges();
  });
});

I think it has to be related with the lifecycle because if I tried to get the <nav> element, I'm able to.

The problem arise when I tried to access an element inside the for loop.

答案1

得分: 1

  1. 在面包屑初始化后,应检测更改。
  2. 使用 active = truengIf 将为 false,因此 <a> 将不会显示。
英文:
  1. You should detect the changes after the initialization of the breadcrumbs
  2. with active = true, the ngIf will be false so the <a> will not be displayed

答案2

得分: 0

我发现了解决方案,我认为它与detectChanges()方法有关,可能是因为它没有更新组件的breadcrumbs属性。

英文:

I found the solution and I think it's related with the detectChanges() method probably because it wasn't updating the breadcrumbs prop to the component.

test('should match breadcrumb to with href property', async () => {
  component.breadcrumbs = [
    {
      text: 'Test',
      disabled: false,
      to: '/route',
      active: false,
    },
  ];
  fixture.detectChanges();

  const href = compiled.querySelector('a').getAttribute('href');
  expect(href).toBe(component.breadcrumbs[0].to);
});

huangapple
  • 本文由 发表于 2023年5月11日 18:22:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/76226580.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定