测试开玩笑地失败了,在 jasmine 中传递了一个带有@input 的 angular 指令
test fails in jest, passes in jasmine for an angular directive with @input
我在这个晴朗的星期六早上坐下来,目标是将我的 angular 9 项目开个玩笑。失败到此为止。除了 JSDOM 不支持 DragDropEvent 的 ClipboardEvent(对此我有解决方法)之外,在 Jasmine 中通过的测试在 Jest 中失败。
这是我正在测试的内容:
@Directive({
selector: '[evAutoTab]'
})
export class EvAutoTabDirective {
@Input('evAutoTab') target: string;
@HostListener('keyup') onKeyup() {
this.moveFocus();
}
constructor(private el: ElementRef) {
}
private moveFocus() {
const maxLen = this.el.nativeElement.getAttribute('maxlength');
const len = this.el.nativeElement.value.length;
// console.log(`len ${len} maxLen ${maxLen} target ${this.target}`);
if (len === parseInt(maxLen, 10)) {
const next: HTMLElement = document.querySelector('#' + this.target);
next.focus();
}
}
}
在 jest 和 jasmine 配置中,调用了我要测试的指令,但 "target" 从未在 jest 中设置,因此测试失败。 evAutoTab="target".
我相信我已经正确配置了 jest(或者更确切地说 angular 正确配置了 jest)
测试:
@Component({
template: `
<div>
<input evAutoTab="AutoTab1" id="AutoTab0" maxlength="4" value=""/>
<input evAutoTab id="AutoTab1" value=""/>
<input evAutoTab="AutoTab4" id="AutoTab2" maxlength="2" value=""/>
</div>
<div>
<input evAutoTab id="AutoTab3" value=""/>
<input evAutoTab id="AutoTab4" value=""/>
<input evAutoTab id="AutoTab5" value=""/>
</div>
`
})
class TestComponent {
constructor() {
}
}
describe('EvAutoTabDirective', () => {
let component: TestComponent;
let fixture: ComponentFixture<TestComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
TestComponent,
EvAutoTabDirective
]
});
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
});
it('should move focus from third element skipping to fifth', () => {
const debugEl: HTMLElement = fixture.debugElement.nativeElement;
const autoTab2: HTMLInputElement = debugEl.querySelector('#AutoTab2');
const autoTab4: HTMLInputElement = debugEl.querySelector('#AutoTab4');
const focusSpy = spyOn({
here: () => {
}
}, 'here');
// verify setup
autoTab2.focus();
expect(document.activeElement.id).toEqual('AutoTab2');
// act
autoTab2.value = '19';
autoTab2.dispatchEvent(new Event('keyup'));
fixture.detectChanges();
expect(document.activeElement.id).toEqual('AutoTab4');
});
});
有什么建议吗?
所以开玩笑地测试我需要第二个 fixture.detectChanges();
fixture.detectChanges();
fixture.detectChanges();
expect(document.activeElement.id).toEqual('AutoTab4');
现在可以了。
给笑话第二次机会
针对您的回答,您可以通过在创建测试组件时设置自动检测更改来避免此 detectChanges 调用两次
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [TestComponent],
providers:[{ provide: ComponentFixtureAutoDetect, useValue: true }] //<= SET AUTO HERE
})
.compileComponents();
}));
我在这个晴朗的星期六早上坐下来,目标是将我的 angular 9 项目开个玩笑。失败到此为止。除了 JSDOM 不支持 DragDropEvent 的 ClipboardEvent(对此我有解决方法)之外,在 Jasmine 中通过的测试在 Jest 中失败。
这是我正在测试的内容:
@Directive({
selector: '[evAutoTab]'
})
export class EvAutoTabDirective {
@Input('evAutoTab') target: string;
@HostListener('keyup') onKeyup() {
this.moveFocus();
}
constructor(private el: ElementRef) {
}
private moveFocus() {
const maxLen = this.el.nativeElement.getAttribute('maxlength');
const len = this.el.nativeElement.value.length;
// console.log(`len ${len} maxLen ${maxLen} target ${this.target}`);
if (len === parseInt(maxLen, 10)) {
const next: HTMLElement = document.querySelector('#' + this.target);
next.focus();
}
}
}
在 jest 和 jasmine 配置中,调用了我要测试的指令,但 "target" 从未在 jest 中设置,因此测试失败。 evAutoTab="target".
我相信我已经正确配置了 jest(或者更确切地说 angular 正确配置了 jest)
测试:
@Component({
template: `
<div>
<input evAutoTab="AutoTab1" id="AutoTab0" maxlength="4" value=""/>
<input evAutoTab id="AutoTab1" value=""/>
<input evAutoTab="AutoTab4" id="AutoTab2" maxlength="2" value=""/>
</div>
<div>
<input evAutoTab id="AutoTab3" value=""/>
<input evAutoTab id="AutoTab4" value=""/>
<input evAutoTab id="AutoTab5" value=""/>
</div>
`
})
class TestComponent {
constructor() {
}
}
describe('EvAutoTabDirective', () => {
let component: TestComponent;
let fixture: ComponentFixture<TestComponent>;
beforeEach(() => {
TestBed.configureTestingModule({
declarations: [
TestComponent,
EvAutoTabDirective
]
});
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
});
it('should move focus from third element skipping to fifth', () => {
const debugEl: HTMLElement = fixture.debugElement.nativeElement;
const autoTab2: HTMLInputElement = debugEl.querySelector('#AutoTab2');
const autoTab4: HTMLInputElement = debugEl.querySelector('#AutoTab4');
const focusSpy = spyOn({
here: () => {
}
}, 'here');
// verify setup
autoTab2.focus();
expect(document.activeElement.id).toEqual('AutoTab2');
// act
autoTab2.value = '19';
autoTab2.dispatchEvent(new Event('keyup'));
fixture.detectChanges();
expect(document.activeElement.id).toEqual('AutoTab4');
});
});
有什么建议吗?
所以开玩笑地测试我需要第二个 fixture.detectChanges();
fixture.detectChanges();
fixture.detectChanges();
expect(document.activeElement.id).toEqual('AutoTab4');
现在可以了。
给笑话第二次机会
针对您的回答,您可以通过在创建测试组件时设置自动检测更改来避免此 detectChanges 调用两次
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [TestComponent],
providers:[{ provide: ComponentFixtureAutoDetect, useValue: true }] //<= SET AUTO HERE
})
.compileComponents();
}));