Как найти существование дочернего компонента в angular, используя `testing-library` - PullRequest
0 голосов
/ 05 ноября 2019

В моем component.html я сохраняю некоторые обязательные дочерние компоненты. Я хотел бы проверить это существование. Также я использую CUSTOM_ELEMENTS_SCHEMA в моем тестовом стенде. если я не использую это, мне нужно добавить еще 20 компонентов в тест, который не используется непосредственно компонентом тестирования.

В этом сценарии, как я могу найти существование дочерних компонентов в тестировании?

Вот мой html:

<section>
    <div class="inner-section">
        <div class="sub-title">
            <h2>Subsystem</h2>
            <button data-testid="btn-addRow" (click)="addRow()" [disabled]="crud.isCreate || crud.isUpdate">
                Add Subsystem
            </button>
        </div>

        <shell-page-navigation
        data-testid="page-navigation"
        *ngIf="pagination"
        [configPageNator]="pageNavigator"
        (pageOptionChange)="pageOptionChange($event)"
        (turnPage)="turnPage($event)"
        (setCurrentPage)="setCurrentPage($event)"
        ></shell-page-navigation>

        <form data-testid="form-subsystem" [formGroup]="createForm" (ngSubmit)="onCreateFormSubmit()" >
            <span class="form-indication"><sup>*</sup> Indicates required</span>
            <!-- <span class="error-resubmit" *ngIf="reSubmits">These fields have errors which need to be resolved before you can submit the configuration</span> -->

            <table class="ibo-table">
                <thead>
                    <tr class="row-head">
                        <th *ngFor="let col of columns;" [ngClass]="col.class">
                            {{col.title}}
                            <ng-container *ngIf="col.data === 'Name'"><sup>*</sup></ng-container>
                            <div class="row-header-menu" *ngIf="col.filter">
                                <a href="#" class="row-head-menu" (click)="toggleFilterMenu(col.title); false"></a>
                                <div class="menu-content" *ngIf="showFilter === col.title">
                                    <ul class="header-menu">
                                        <li class="sort-group divide">
                                            <label>
                                                <input type="radio" value="asc" aria-label="Sort by ascending order" (change)="setSort($event.target.value, col.data)" name="sortOrder">
                                                <span class="ibo-radio" [ngClass]="{'active':position && sortBy === col.data}"></span>
                                                Sort by ascending order
                                            </label>
                                        </li>
                                        <li class="sort-group divide">
                                            <label>
                                                <input type="radio" value="des" aria-label="Sort by descending order" (change)="setSort($event.target.value, col.data)" name="sortOrder">
                                                <span class="ibo-radio" [ngClass]="{'active':!position && sortBy === col.data }"></span>
                                                Sort by descending order
                                            </label>
                                        </li>

                                        <li class="ibo-btn">
                                            <button (click)="applyFilterOptions(); false"  aria-label="Apply"  class="ibo-btn-true">Apply</button>
                                            <button (click)="toggleFilterMenu(''); false"  aria-label="Cancel"  class="ibo-btn-false">Cancel</button>
                                        </li>
                                    </ul>
                                </div>
                            </div>
                        </th>
                    </tr>
                </thead>

                <tbody>
                    <tr *ngIf="crud.isCreate" [ngClass]="{'create' : crud?.isCreate}">
                        <td *ngFor="let col of columns;" [ngClass]="col.class">
                            <ng-container *ngIf="col.data !== ''">
                                <input id="name" type="text"
                                class="form-control"
                                formControlName={{col.data}}
                                placeholder={{col.placeholder}}>
                                <control-messages [control]="createForm.controls[col.data]"></control-messages>
                            </ng-container>
                            <ng-container *ngIf="col.data === ''">
                                <button type="submit" aria-label="Ok" class="apply-item"></button>
                                <button type="button" aria-label="Cancel" (click)="confirmCancel(); false" class="cancel-apply"></button>
                            </ng-container>
                        </td>
                    </tr>
                    <tr *ngFor="let data of subsystems;" [ngClass]="{'edit': data.Id === crud.updateData?.Id}">
                        <td *ngFor="let col of columns" [ngClass]="col.class">
                            <ng-container *ngIf="data.Id !== crud.updateData?.Id">
                                <ng-container *ngIf="col.data !== ''">
                                    {{getData(data,col.data)}}
                                </ng-container>
                                <ng-container *ngIf="col.data === ''">
                                    <button type="button" aria-label="Edit" class="edit-item" (click)="editSubsytem(data)"></button>
                                    <button type="button" aria-label="Delete" *ngIf="data.IsDeletePossible" (click)="confirmRemoveSubsytem(data); false" class="delete-item"></button>
                                </ng-container>
                            </ng-container>
                            <ng-container *ngIf="data.Id === crud.updateData?.Id">
                                <ng-container *ngIf="col.data !== ''">
                                    <input id="name" type="text" class="form-control"
                                    formControlName={{col.data}} placeholder={{col.title}}>
                                    <control-messages [control]="createForm.controls[col.data]"></control-messages>
                                </ng-container>
                                <ng-container *ngIf="col.data === ''">
                                    <button type="submit" aria-label="Ok" class="apply-item"></button>
                                    <button type="button" aria-label="Cancel" (click)="confirmCancel(); false" class="cancel-apply"></button>
                                </ng-container>
                            </ng-container>

                        </td>
                    </tr>
                </tbody>
            </table>
        </form>

        <shell-page-navigation
        *ngIf="pagination"
        [configPageNator]="pageNavigator"
        (pageOptionChange)="pageOptionChange($event)"
        (turnPage)="turnPage($event)"
        (setCurrentPage)="setCurrentPage($event)"
        ></shell-page-navigation>

    </div>
</section>

<shell-modals-popup [popConfig]='popConfig' (reset)="reset()"></shell-modals-popup>

мой тестовый файл спецификации:

import { render } from '@testing-library/angular';
import { getByTestId } from '@testing-library/dom';

import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { SubSystemComponent } from './sub-system.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { StoreModule } from '@ngrx/store';
import { reducer } from './../../../state/reducers/reducer';
import { EffectsModule } from '@ngrx/effects';
import { EffectsSubSystem } from './../../../state/effects/subSystem.effects';
import { ModelSubSystem } from './../../../models/model.subSystem';

test('renders the current value', async () => {

    const data1 = {
        Id: 1,
        Name: 'subsystem1',
        IsDeletePossible: true,
        CreatedBy: '',
        CreatedDate: new Date(),
        UpdatedBy: '',
        UpdatedDate: new Date(),
        UpdatedByName: '',
        CreatedByName: ''
    } as ModelSubSystem;

    const data2 = {
        Id: 2,
        Name: 'subsystem2',
        IsDeletePossible: true,
        CreatedBy: '',
        CreatedDate: new Date(),
        UpdatedBy: '',
        UpdatedDate: new Date(),
        UpdatedByName: '',
        CreatedByName: ''
    } as ModelSubSystem;

    const component = await render(SubSystemComponent, {

        schemas: [CUSTOM_ELEMENTS_SCHEMA],
        imports: [
            HttpClientTestingModule,
            FormsModule,
            ReactiveFormsModule,
            StoreModule.forRoot({}, { runtimeChecks: { strictStateImmutability: true, strictActionImmutability: true } }),
            StoreModule.forFeature('pfservice', reducer),
            EffectsModule.forRoot([]),
            EffectsModule.forFeature([EffectsSubSystem])
        ],
        componentProperties: {
            subsystems : [data1, data2]
        }

    });

    const container = document.body;
    expect(getByTestId(container, 'btn-addRow')).toBeTruthy();
    expect(getByTestId(container, 'page-navigation')).toBeTruthy(); //fails..
    expect(getByTestId(container, 'form-subsystem')).toBeTruthy();

});

Кто-нибудь, пожалуйста, помогите мне?

Ответы [ 2 ]

1 голос
/ 05 ноября 2019

Вам нужно будет добавить дочерний компонент в объявления:


    const component = await render(SubSystemComponent, {
        declarations: [ChildComponent],
        ...
    });

0 голосов
/ 05 ноября 2019

Существует отличная библиотека, отвечающая вашим требованиям: ng-mocks

Я использую ее, и очень легко издеваться над вашим компонентом и играть с ними.

Вам просто нужно следующее, чтобы высмеивать все ваши дочерние компоненты:

MockComponents(ChildComponent1, ChildComponent2, ChildComponent3 ...),

А чтобы пойти дальше, вы можете найти ниже обобщенную функцию, чтобы легко получить нужный компонент:

export function getComponent<T>(fixture: ComponentFixture<any>, comp: Type<T>, index: number = 0): T {
  return fixture.debugElement
    .queryAll(By.directive(comp))[index]
    .componentInstance as T;
}

так что в своем тесте вы можете сделать:

getComponent(fixture, Component1).valueChangeB.emit( XXX )

expect(getComponent(fixture, Component1).valueA).toBe('some-value')
...