#javascript #angular #unit-testing #jasmine #karma-jasmine
#javascript #angular #модульное тестирование #jasmine #карма-жасмин
Вопрос:
У меня есть setTimeout
внутри ngOnInit
, чтобы определить некоторые свойства и запустить функцию. Я хочу протестировать это, но это не входит в setTimeout
, пытался использовать tick()
и fakeAsync
.
Мой код для покрытия модульным тестом Jasmine:
ngOnInit() {
setTimeout(() => {
this.container = document.querySelector(`#field-${this.id}`);
this.inputField = document.querySelector(`#${this.id}`);
this.getState();
}, 50);
}
getState() {
this.inputField.addEventListener('focus', () => {
const tooltip = this.container.querySelector('.tooltip');
const tooltipHeight = tooltip.querySelector('p').clientHeight;
tooltip.style.height = tooltipHeight 'px';
});
this.inputField.addEventListener('blur', () => {
const tooltip = this.container.querySelector('.tooltip');
tooltip.style.height = '0px';
});
}
Что я сделал, чтобы покрыть это:
it('should ', fakeAsync(() => {
const fixture = TestBed.createComponent(TooltipComponent);
const componentInst = fixture.componentInstance;
componentInst.id = 'fieldId';
tick();
fixture.detectChanges();
fixture.whenStable().then(() => {
const tooltipContainer = fixture.debugElement.query(By.css('#fieldId'));
expect(componentInst.container ).toBe(tooltipContainer );
});
}));
Но это не входит в setTimeout
функцию, я думаю, мне нужно шпионить document.querySelector
.
Как я могу покрыть эту setTimeout
функцию?
Комментарии:
1. вам нужно вызвать
tick()
после регистрации таймера, который послеngOnInit()
вызывается (помещаетсяtick()
послеfixture.detectChanges()
)2. @MikeS. да, я пробовал и это, но все то же самое. Это не входит в
setTimeout(() => {
3.
tick()
просто разрешает обещания. Вы должны указать число, чтобы указать, сколько времени вы хотите пройти. Так что делайте то, что @MikeS. сказано так же, какtick(50)
и вместоtick()
.
Ответ №1:
Вам нужно вызвать ngOnInit
метод компонента, затем вызвать tick(50)
;
Чтобы вызвать ngOnInit
, вы должны fixture.detectChanges()
сначала вызвать.
Документ о detectChanges
:
Вызовите его для инициализации компонента (он вызывает ngOnInit) и после вашего тестового кода измените значения свойств компонента, связанные с данными
Рабочий пример:
tooltip.component.ts
:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-tooltip',
template: `<div [id]="'field-' id">
<input [id]="id" />
</div>`,
})
export class TooltipComponent implements OnInit {
id = 'name';
container: any;
inputField: any;
ngOnInit() {
setTimeout(() => {
this.container = document.querySelector(`#field-${this.id}`);
this.inputField = document.querySelector(`#${this.id}`);
this.getState();
}, 50);
}
getState() {
this.inputField.addEventListener('focus', () => {
const tooltip = this.container.querySelector('.tooltip');
const tooltipHeight = tooltip.querySelector('p').clientHeight;
tooltip.style.height = tooltipHeight 'px';
});
this.inputField.addEventListener('blur', () => {
const tooltip = this.container.querySelector('.tooltip');
tooltip.style.height = '0px';
});
}
}
tooltip.component.spec.ts
:
import { fakeAsync, TestBed, tick } from '@angular/core/testing';
import { TooltipComponent } from './tooltip.component';
fdescribe('65212730', () => {
it('should pass', fakeAsync(() => {
const fixture = TestBed.createComponent(TooltipComponent);
const componentInst = fixture.componentInstance;
componentInst.id = 'fieldId';
const getStateStub = spyOn(componentInst, 'getState').and.stub();
fixture.detectChanges();
tick(50);
fixture.whenStable().then(() => {
expect(componentInst.container.nodeName).toBe('DIV');
expect(componentInst.inputField.nodeName).toBe('INPUT');
expect(getStateStub).toHaveBeenCalledTimes(1);
});
}));
});
результат модульного теста с покрытием:
Комментарии:
1. хорошо, что это работает, но функция
getState()
не покрыта,this.container
иthis.inputField
свойства задаются с помощью aquerySelector
, которые оба поступают из другого компонента в DOM. Теперь вы определили это в компоненте всплывающей подсказки.TooltipComponent
Включает только сообщение всплывающей подсказки. Как я могу покрыть функциюgetState()
?2. Потому что я заглушил
getState()
метод и толькоngOnInit
метод тестирования.