gpt4 book ai didi

unit-testing - 如何使用 ng-template 测试模态元素以及触发它的操作?

转载 作者:行者123 更新时间:2023-12-03 16:23:40 25 4
gpt4 key购买 nike

我读了 Angular Testing我不确定是否有任何关于在模态内测试元素以及如何检查自定义操作的引用。我的目的是编写必要的测试表明我将确保我的函数和模态按预期工作。

由于模态被隐藏,检查模态元素是否出现的测试失败。所以我想这里缺少一些东西。

这是我的 photos.components.ts文件:

import {Component, OnInit, ViewEncapsulation} from '@angular/core';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';

@Component({
selector: 'app-photos',
templateUrl: './photos.component.html',
styleUrls: ['./photos.component.scss'],
encapsulation: ViewEncapsulation.None
})
export class PhotosComponent implements OnInit {

constructor(private modalService: NgbModal) { }

openDarkModal(content) {
this.modalService.open(content, { windowClass: 'dark-modal', size: 'lg', centered: true });
}

ngOnInit() {
}

}

这是我的 photos.component.html文件:
<div>
<div class="col-lg-4 col-sm-6 mb-3">
<a><img (click)="openDarkModal(content)" id="photo-one" class="img-fluid z-depth-4 relative waves-light" src="#" alt="Image" data-toggle="content" data-target="#content"></a>
</div>
</div>

<!-- Dark Modal -->
<ng-template #content let-modal id="ng-modal">
<div class="modal-header dark-modal">
<img (click)="modal.dismiss('Cross click')" id="modal-image" class="embed-responsive-item img-fluid" src="#" alt="Image" allowfullscreen>
</div>
<div class="justify-content-center flex-column flex-md-row list-inline">
<ul class="list-inline flex-center text-align-center text-decoration-none" id="modal-buttons-list">
<li><a style="color: white;" href="#"><button mdbBtn type="button" size="sm" class="waves-light" color="indigo" mdbWavesEffect><i class="fab fa-facebook-f"></i></button></a></li>
<li><a style="color: white;" href="#"><button mdbBtn type="button" size="sm" class="waves-light" color="cyan" mdbWavesEffect><i class="fab fa-twitter"></i></button></a></li>
<li><a style="color: white;" href="#"><button mdbBtn type="button" size="sm" class="waves-light btn btn-blue-grey" mdbWavesEffect><i class="fas fa-envelope"></i></button></a></li>
</ul>
</div>
</ng-template>

这就是我与 photos.component.spec.ts 在一起的地方文件:

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { PhotosComponent } from './photos.component';
import { NO_ERRORS_SCHEMA } from '@angular/core';

describe('PhotosComponent', () => {
let component: PhotosComponent;
let fixture: ComponentFixture<PhotosComponent>;

beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ PhotosComponent ],
schemas: [NO_ERRORS_SCHEMA]
})
.compileComponents();
}));

beforeEach(() => {
fixture = TestBed.createComponent(PhotosComponent);
component = fixture.componentInstance;
});

it('should create', () => {
expect(component).toBeTruthy();
});

it('should render the first photo', () => {
const compiled = fixture.debugElement.nativeElement;
expect(compiled.querySelector('#photo-one')).toBeTruthy();
});
});

我需要 中元素的测试用例深色模态 以及 的测试openDarkModal .除了代码之外,对于初学者的 Angular 7 测试中的引用将不胜感激。

最佳答案

让我帮你解决这个问题。让我们说你有
app.component.html

<div id="title">
{{title}}
</div>
<ng-template #content
let-modal
id="ng-modal">
<div class="modal-header dark-modal">
Header
</div>
<div class="justify-content-center flex-column flex-md-row list-inline">
Body
</div>
</ng-template>
app.component.ts
import { Component, ViewChild, TemplateRef } from '@angular/core';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
})
export class AppComponent {
title = 'AngularProj';
@ViewChild('content') modalRef: TemplateRef<any>;
}
你需要写 spec文件方式略有不同:
app.component.spec.ts
import { TestBed, async, ComponentFixture } from '@angular/core/testing';
import { AppComponent } from './app.component';
import { ViewChild, Component, OnInit, AfterContentInit, TemplateRef } from '@angular/core';
import { By } from '@angular/platform-browser';

@Component({
template: `
<ng-container *ngTemplateOutlet="modal"> </ng-container>
<app-root></app-root>
`,
})
class WrapperComponent implements AfterContentInit {
@ViewChild(AppComponent) appComponentRef: AppComponent;
modal: TemplateRef<any>;
ngAfterContentInit() {
this.modal = this.appComponentRef.modalRef;
}
}

describe('AppComponent', () => {
let app: AppComponent;
let fixture: ComponentFixture<WrapperComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [WrapperComponent, AppComponent],
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(WrapperComponent);
const wrapperComponent = fixture.debugElement.componentInstance;
app = wrapperComponent.appComponentRef;
fixture.detectChanges();
});
it('should create the app', async(() => {
expect(app).toBeDefined();
}));
it('should have title in HtmL ', () => {
const titleText = (fixture.debugElement.nativeElement.querySelector('#title').innerText);
expect(titleText).toBe('AngularProj');
});
it('should have Header in HtmL ', () => {
const headerText = (fixture.debugElement.queryAll(By.css('.modal-header.dark-modal'))[0].nativeElement.innerText);
expect(headerText).toBe('Header');
});
});
  • 如您所见,我包裹了 app-root带有示例测试组件 ( WrapperComponent )。
  • 从,app-rootng-template ,所以它不会自己渲染。这会造成一个棘手的情况,因为我们需要渲染 app.component 的这一部分。 .
  • 曝光 ng-template通过创建 @ViewChild('content') modalRef: TemplateRef<any>;然后使用它在内部渲染 WrapperComponent .

  • 我知道这似乎是一种黑客行为,但在我阅读的所有文章中,这就是我们实现这一目标的方式。

    用于测试类似的东西:
    openDarkModal(content) {
    this.modalService.open(content, { windowClass: 'dark-modal', size: 'lg', centered: true });
    }
    您可以使用 spy ,但在此之前使 modalService公开,以便它可以被监视:
    constructor(public modalService: NgbModal) { }
    您也可以使用 jasmine.createSpyObj并保持服务 private .
    然后在 spec :
       import { NgbModalModule } from '@ng-bootstrap/ng-bootstrap';

    TestBed.configureTestingModule({
    imports: [NgbModalModule],
    declarations: [PhotosComponent, /*WrapperComponent*/],
    schemas: [NO_ERRORS_SCHEMA],
    })

    // and in it block
    it('should call modal Service open function when clicked ', async(() => {
    spyOn(component.modalService,'open').and.callThrough();
    const openModalEle= fixture.debugElement.nativeElement.querySelector('#photo-one'));
    openModalEle.click();
    expect(component.modalService.open).toHaveBeenCalled();
    }));
    更新:
    使用 Angular 11,您需要进行一些更改:
    @Component({
    template: `
    <div>
    <ng-container *ngTemplateOutlet="modal"> </ng-container>
    </div>
    <app-root> </app-root>
    `,
    })
    class WrapperComponent implements AfterViewInit {
    @ViewChild(AppComponent) appComponentRef: AppComponent;
    modal: TemplateRef<any>;
    constructor(private cdr: ChangeDetectorRef) {}
    ngAfterViewInit() {
    this.modal = this.appComponentRef.modalRef;
    this.cdr.detectChanges();
    }
    }
    describe('AppComponent', () => {
    let fixture: ComponentFixture<WrapperComponent>;
    let wrapperComponent: WrapperComponent;

    beforeEach(
    waitForAsync(() => {
    TestBed.configureTestingModule({
    declarations: [WrapperComponent, AppComponent],
    imports: [ModalModule.forRoot()],
    }).compileComponents();
    })
    );
    beforeEach(() => {
    fixture = TestBed.createComponent(WrapperComponent);
    wrapperComponent = fixture.debugElement.componentInstance;
    fixture.detectChanges();
    });
    it('should create the app', () => {
    expect(wrapperComponent).toBeDefined();
    expect(wrapperComponent.appComponentRef).toBeDefined();
    });
    });

    关于unit-testing - 如何使用 ng-template 测试模态元素以及触发它的操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55927441/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com