[英]How can I test a modal's elements with ng-template and the action that triggers it?
I read the Angular Testing and I'm not sure if there is any reference about testing elements inside a modal and how to check custom actions.我阅读了Angular Testing ,我不确定是否有任何关于模态内测试元素以及如何检查自定义操作的参考。 My purpose is to write the necessary tests show I will be sure that my function and the modal works as expected.
我的目的是编写必要的测试以确保我的函数和模式按预期工作。
As the modal is hidden, the tests to check if the elements of the modal appear, fail.由于模态被隐藏,检查模态元素是否出现的测试失败。 So I suppose that there is something missing here.
所以我想这里缺少一些东西。
This is my photos.components.ts
file:这是我的
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() {
}
}
This is my photos.component.html
file:这是我的
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>
and this is where I am with the photos.component.spec.ts
file:这就是我处理
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();
});
});
I need the test cases for the elements inside the Dark Modal and the test for the openDarkModal .我需要Dark Modal内部元素的测试用例和openDarkModal的测试。 Except for the code, a reference in Angular 7 testing for beginners would be appreciated.
除了代码外,如果有适合初学者的 Angular 7 测试参考,我们将不胜感激。
Let me help you with this one.让我帮你解决这个问题。 Lets say you have
可以说你有
app.component.html应用程序组件.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应用程序组件.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>;
}
You need to write spec
file with slightly different way:您需要以稍微不同的方式编写
spec
文件:
app.component.spec.ts 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
with a sample testing component ( WrapperComponent
).WrapperComponent
) 包装了app-root
。app-root
has ng-template
, so it won't render on it's own.app-root
有ng-template
,所以它不会自己渲染。 This creates a tricky situation as we need to render this part of the app.component
.app.component
的这一部分。ng-template
by creating @ViewChild('content') modalRef: TemplateRef<any>;
@ViewChild('content') modalRef: TemplateRef<any>;
公开ng-template
and then using it to render inside WrapperComponent
.WrapperComponent
内渲染。 I know it seems like a hack but over all the articles I went through, that's how we can achieve this.我知道这看起来像是 hack,但在我阅读的所有文章中,这就是我们实现这一目标的方式。
For testing something like:用于测试类似的东西:
openDarkModal(content) {
this.modalService.open(content, { windowClass: 'dark-modal', size: 'lg', centered: true });
}
you can use spy
, but before that make modalService
public so that it can be spied upon:您可以使用
spy
,但在此之前将modalService
公开以便可以对其进行监视:
constructor(public modalService: NgbModal) { }
You can also use jasmine.createSpyObj
and keep the service private
.您还可以使用
jasmine.createSpyObj
并将服务private
。
and then in spec
:然后在
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();
}));
with Angular 11, there are few changes which you will require:使用 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();
});
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.