У меня есть приложение, в котором я меняю значение input
, и оно должно немедленно изменить значение h1
. Он хорошо работает при проверке вручную (изменение input
изменяет h1
), но не работает в тесте (изменение input
не влияет на содержимое h1
).
Я дважды проверил, вызываю ли я detectChanges
и whenStable
, когда должен я думаю, но мне все равно не повезло.
Может кто-нибудь заметить, что я делаю неправильно?
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<form>
<input type = "text" name = "query-input" [(ngModel)] = "myText" />
</form>
<h1>H1 content is "{{myText}}"</h1>
`
})
export class AppComponent implements OnInit {
public myText = 'Default value';
ngOnInit(): void {
this.myText = 'Value from ngOnInit';
}
}
import { TestBed, async } from '@angular/core/testing';
import { AppComponent } from './app.component';
import { FormsModule } from '@angular/forms';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
FormsModule
],
declarations: [
AppComponent
],
}).compileComponents();
}));
it('should work', () => {
const fixture = TestBed.createComponent(AppComponent);
console.info(fixture.componentInstance.myText); // VALUE IS OK: "Default value"
fixture.detectChanges();
fixture.whenStable().then(() => {
console.info(fixture.componentInstance.myText); // VALUE IS OK: "Value from ngOnInit"
const compiled = fixture.debugElement.nativeElement;
compiled.querySelector('input').value = 'Value from test';
fixture.detectChanges();
fixture.whenStable().then(() => {
console.info(compiled.querySelector('input').value); // VALUE IS OK: 'Value from test'
console.info(fixture.componentInstance.myText); // VALUE IS UNEXPECTED: 'Value from ngOnInit'
console.info(compiled.querySelector('h1').textContent); // VALUE IS UNEXPECTED: 'H1 content is "Value from ngOnInit"'
});
});
});
});
Итак, в этих двух последних console.info
я получаю Value from ngOnInit
, но я ожидал получить Value from test
Используемая угловая версия: 7.2.0
Нашел проблему, недостаточно изменить value
из input
, после этого нужно вызвать dispatchEvent
.
Итак, этот код:
...
compiled.querySelector('input').value = 'Value from test';
fixture.detectChanges();
...
Необходимо изменить на:
...
compiled.querySelector('input').value = 'Value from test';
compiled.querySelector('input').dispatchEvent(new Event('input'));
fixture.detectChanges();
...
Если предыдущее решение вам не подходит, попробуйте отправить событие blur
после input
. Я наткнулся на один случай, когда input
было недостаточно.