我试图测试注入到我创建的模拟类中的组件。尽管当我尝试测试其存在时该组件有效,但它返回null。
可注射成分:
import { Injectable, ElementRef, Renderer2, RendererFactory2 } from '@angular/core';
@Injectable()
export class NgBackdropComponent {
private renderer: Renderer2;
private appElementRef: ElementRef;
message: string = 'Carregando...';
constructor(rendererFactory: RendererFactory2) {
this.renderer = rendererFactory.createRenderer(null, null);
this.appElementRef = new ElementRef(<Element>document.getElementsByTagName('body').item(0));
}
show() {
const divSpinnerItem1 = this.renderer.createElement('i');
const divSpinnerItem2 = this.renderer.createElement('i');
const divSpinnerItem3 = this.renderer.createElement('i');
const divSpinner = this.renderer.createElement('div');
this.renderer.addClass(divSpinner, 'spinner');
this.renderer.appendChild(divSpinner, divSpinnerItem1);
this.renderer.appendChild(divSpinner, divSpinnerItem2);
this.renderer.appendChild(divSpinner, divSpinnerItem3);
const spanMensagem = this.renderer.createElement('span');
spanMensagem.innerHTML = this.message;
const div = this.renderer.createElement('div');
this.renderer.addClass(div, 'lock-content');
this.renderer.appendChild(div, divSpinner);
this.renderer.appendChild(div, spanMensagem);
this.renderer.appendChild(this.appElementRef.nativeElement, div);
}
hide() {
const elemento = this.appElementRef.nativeElement.querySelector('.lock-content');
if (elemento) {
elemento.remove();
}
}
}
我的测试环境:
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NgBackdropComponent } from './ng-backdrop.component';
import { Component } from '@angular/core';
import { By } from '@angular/platform-browser';
@Component({
template: `
<button (click)="clickButton()"></button>
`
})
class MockNgBackdropComponent {
constructor(private backdrop: NgBackdropComponent) { }
clickButton() {
this.backdrop.message = 'Teste BackDrop aesdas';
this.backdrop.show();
console.log('iniciei backdrop');
}
closeBackdrop() {
this.backdrop.hide();
}
}
describe('NgBackdropComponent', () => {
let component: MockNgBackdropComponent;
let fixture: ComponentFixture<MockNgBackdropComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [MockNgBackdropComponent],
providers: [NgBackdropComponent]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MockNgBackdropComponent);
component = fixture.componentInstance;
});
describe('Deve injetar', async () => {
it('Deve ter uma div principal', function () {
const btnClick = fixture.nativeElement.querySelector('button');
btnClick.click();
fixture.detectChanges();
const el = fixture.nativeElement.querySelector('.lock-content');
console.log(el);
expect(el).toBeTruthy();
});
});
});
在测试中,我创建了一个Mock类,将组件注入其中。 我不明白为什么它找不到类,因为它存在。
答案 0 :(得分:1)
之所以无法在组件中找到它,是因为您没有在组件中创建它。如果您在构造函数中查看以下行:
this.appElementRef = new ElementRef(<Element>document.getElementsByTagName('body').item(0))
您直接在<body>
元素中的文档上创建它。如果您在自己的规范中进行搜索,则会在此处找到它。我创建了STACKBLITZ来向您展示我的意思。这是该堆叠闪电战的规格:
it('Deve ter uma div principal', () => {
const btnClick = fixture.nativeElement.querySelector('button');
console.log(btnClick);
btnClick.click();
fixture.detectChanges();
const appElementRef = new ElementRef(<Element>document.getElementsByTagName('body').item(0));
const el = appElementRef.nativeElement.querySelector('.lock-content');
expect(el).toBeTruthy();
});
如果您console.log(appElementRef)
,您会注意到它的tagName是body
,并注意其nativeElement.innerHTML的内容。这看起来像是“漂亮”:
<body>
<div class="jasmine_html-reporter">
<div class="jasmine-banner"><a class="jasmine-title" href="http://jasmine.github.io/" target="_blank"></a><span
class="jasmine-version">3.3.0</span></div>
<ul class="jasmine-symbol-summary"></ul>
<div class="jasmine-alert"></div>
<div class="jasmine-results">
<div class="jasmine-failures"></div>
</div>
</div>
<div id="nprogress" style="transition: none 0s ease 0s; opacity: 1;">
<div class="bar" role="bar" style="transform: translate3d(0%, 0px, 0px); transition: all 200ms ease 0s;">
<div class="peg"></div>
</div>
</div>
<div id="root0" ng-version="7.0.1">
<button></button>
</div>
<div class="lock-content">
<div class="spinner">
<i></i>
<i></i>
<i></i>
</div>
<span>Teste BackDrop aesdas</span>
</div>
</body>
请注意,该按钮是如何使用id="root0"
在div中创建的?但是,带有class="lock-content"
的div是在根<body>
元素的附近创建的,因此不在组件的div之内。
实际上,您在console.log(fixture.nativeElement)
上看到的很清楚,并且看到tagName是“ div”,其innerHTML是<button></button>
,它具有两个属性:id: "root0"
和ng-version: "7.0.1"
。放在一起,看起来像这样:
<div id="root0" ng-version="7.0.1">
<button></button>
</div>
因此您可以清楚地看到,因为在组件外部创建了div,所以找不到在组件中创建的div。
我希望这会有所帮助。
答案 1 :(得分:0)
我认为您应该使用DebugElement,例如:
it('Deve ter uma div principal', function () {
const btnClick = fixture.debugElement.query(By.css('button'));
btnClick.click();
fixture.detectChanges();
const el = fixture.debugElement.query(By.css('.lock-content'));
console.log(el);
expect(el).toBeTruthy();
});
关注this link以获取更多信息。