当使用禁用但未禁用的querySelector属性时,用于验证按钮禁用的Angular 6单元测试用例失败
我是Angular的新手,尝试使用Jasmine编写2个单元测试用例。一个测试用于按钮启用时,另一个测试用于按钮禁用时。当使用禁用但未禁用的querySelector属性时,用于验证按钮禁用的Angular 6单元测试用例失败,angular,typescript,unit-testing,jasmine,Angular,Typescript,Unit Testing,Jasmine,我是Angular的新手,尝试使用Jasmine编写2个单元测试用例。一个测试用于按钮启用时,另一个测试用于按钮禁用时。 这是要求……当用户在文本框中输入有效数据时,按钮被启用。如果用户在文本框中输入无效数据,则该按钮将被禁用。初始值已禁用。 这是文本框和按钮html: <input type="text" matInput formControlName = 'triplegOriginControl' [(ngMode
这是要求……当用户在文本框中输入有效数据时,按钮被启用。如果用户在文本框中输入无效数据,则该按钮将被禁用。初始值已禁用。 这是文本框和按钮html:
<input
type="text"
matInput
formControlName = 'triplegOriginControl'
[(ngModel)]="leg.originId"
[matAutocomplete]="autoTripLegOrigin"
class = 'trip-origin-input'
(keydown.Tab)="onKey($event)"
/>
<mat-autocomplete autoActiveFirstOption #autoTripLegOrigin="matAutocomplete">
<mat-option
*ngFor="let option of triplegOriginOptions | async"
[value]="option"
>
{{ option }}
</mat-option>
</mat-autocomplete>
<mat-error *ngIf="triplegForm.controls['triplegOriginControl'].hasError('invalid')">
Please select a valid location
</mat-error>
</mat-form-field>
....
<mat-toolbar color="primary">
<button
mat-raised-button
color="primary"
id="mat-toolbar__get-rate-button-id"
[disabled] = !triplegForm.valid
>
GET RATE
</button>
</mat-toolbar>
这是两个单元测试
describe('Enable or Disable Get Rates Button', () => {
beforeEach(() => {
fetchDataService.locationArray = ["STOC/4958", "NSGR/4143", "ZCRC/416", "NSGR/4143"];
});
it('should enable the button when Origin and Destination are valid', (done) => {
const compiled = fixture.debugElement.nativeElement;
const originIdInput = compiled.querySelector(
".trip-origin-input"
);
originIdInput.value = "STOC/4958";
originIdInput.dispatchEvent(new Event("input"));
const destinationIdInput = compiled.querySelector(
".trip-destination-input"
);
destinationIdInput.value = "NSGR/4143";
destinationIdInput.dispatchEvent(new Event("input"));
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(fixture.componentInstance.leg.originId).toBe('STOC/4958');
expect(fixture.componentInstance.leg.destinationId).toBe('NSGR/4143');
expect(compiled.querySelector('#mat-toolbar__get-rate-button-id').disable).toBeFalsy();
done();
});
});
it('should disable the button when Origin and Destination are invalid', (done) => {
const compiled = fixture.debugElement.nativeElement;
const originIdInput = compiled.querySelector(
".trip-origin-input"
);
originIdInput.value = "546";
originIdInput.dispatchEvent(new Event("input"));
const destinationIdInput = compiled.querySelector(
".trip-destination-input"
);
destinationIdInput.value = "NSGxx/43";
destinationIdInput.dispatchEvent(new Event("input"));
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(fixture.componentInstance.leg.originId).toBe('546');
expect(fixture.componentInstance.leg.destinationId).toBe('NSGxx/43');
expect(compiled.querySelector('#mat-toolbar__get-rate-button-id').disable).toBeTruthy();
done();
});
});
});
使用时:
expect(compiled.querySelector('#mat-toolbar__get-rate-button-id').disable)
第一次测试(有效测试)失败。
错误:预期true为false。
使用属性disabled时,有效测试通过
使用时
expect(compiled.querySelector('#mat-toolbar__get-rate-button-id').disabled)
第二次测试(无效测试)失败。
**错误:预期未定义为真实**
使用属性disable时,无效测试通过
属性禁用与禁用之间有什么区别?
代码按预期工作。当用户输入无效值时,按钮被禁用。当输入有效值时,按钮被启用。
如何更正这些测试用例我认为
.disable
使用JavaScript/HTML禁用输入,我不确定.disabled
的作用。我将使用属性选择器检查属性
1.compiled
在更改和更改检测之前仍然引用DOM/HTML,每次更改时都需要一个新的引用
2.)使用[disabled]属性CSS选择器,查看它何时存在或何时不存在
试试这个,我添加了一些评论:
it('should enable the button when Origin and Destination are valid', (done) => {
const compiled = fixture.debugElement.nativeElement;
const originIdInput = compiled.querySelector(
".trip-origin-input"
);
originIdInput.value = "STOC/4958";
originIdInput.dispatchEvent(new Event("input"));
const destinationIdInput = compiled.querySelector(
".trip-destination-input"
);
destinationIdInput.value = "NSGR/4143";
destinationIdInput.dispatchEvent(new Event("input"));
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(fixture.componentInstance.leg.originId).toBe('STOC/4958');
expect(fixture.componentInstance.leg.destinationId).toBe('NSGR/4143');
// since you did fixture.detectChanges, you need a new reference to the dom
// compiled is still pointing to the previous instance.
const newCompiled = fixture.debugElement.nativeElement;
// attach the attribute selector of [disabled] and expect it to not be there
console.log(!component.triplegForm.valid); // ensure you see false here
expect(newCompiled.querySelector('#mat-toolbar__get-rate-button-id[disabled]')).toBeFalsy();
done();
});
});
it('should disable the button when Origin and Destination are invalid', (done) => {
const compiled = fixture.debugElement.nativeElement;
const originIdInput = compiled.querySelector(
".trip-origin-input"
);
originIdInput.value = "546";
originIdInput.dispatchEvent(new Event("input"));
const destinationIdInput = compiled.querySelector(
".trip-destination-input"
);
destinationIdInput.value = "NSGxx/43";
destinationIdInput.dispatchEvent(new Event("input"));
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(fixture.componentInstance.leg.originId).toBe('546');
expect(fixture.componentInstance.leg.destinationId).toBe('NSGxx/43');
// same logic here
console.log(!component.triplegForm.valid); // ensure you see true here
const newCompiled = fixture.debugElement.nativeElement;
expect(newCompiled.querySelector('#mat-toolbar__get-rate-button-id[disabled]')).toBeTruthy();
done();
});
});
尝试了你的建议,但失败了,出现了另一个错误:错误:预期。。。对falsy进行了仔细研究,发现如果我使用此选择器,有效测试将通过:#mat-toolbar_uuget-rate-button-id已禁用,但如果我使用此选择器,无效测试将失败。如果我使用这个选择器#mat-toolbar uu get-rate-button-id[disabled]无效案例通过它是一个假阳性,它通过了,因为它不在那里。我对CSS选择器很有信心,可能有一种类型,但是CSS选择器需要
[]
(硬括号)。查看console.log of!我添加了component.tripleForm.valid并确保您看到准确的值。如果值准确,可能需要在then回调的fixture.whenStable()
之后再添加一个fixture.detectChanges()
。对于这两种情况,component.tripleForm.valid都为false。valid标志使用自定义验证器。此验证器转到服务以获取有效位置。服务已初始化:*在每个(()=>{fetchDataService.locationArray=[“UPPH/4097”、“CACN/4030”、“ZCRC/416”、“NSGR/4143”、“ZCRC/471”、“REPH/4987”];})之前**找到了…位置数组没有我输入的位置。因此,案例正确无效,因为位置不在数组中。非常感谢你的帮助!
it('should enable the button when Origin and Destination are valid', (done) => {
const compiled = fixture.debugElement.nativeElement;
const originIdInput = compiled.querySelector(
".trip-origin-input"
);
originIdInput.value = "STOC/4958";
originIdInput.dispatchEvent(new Event("input"));
const destinationIdInput = compiled.querySelector(
".trip-destination-input"
);
destinationIdInput.value = "NSGR/4143";
destinationIdInput.dispatchEvent(new Event("input"));
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(fixture.componentInstance.leg.originId).toBe('STOC/4958');
expect(fixture.componentInstance.leg.destinationId).toBe('NSGR/4143');
// since you did fixture.detectChanges, you need a new reference to the dom
// compiled is still pointing to the previous instance.
const newCompiled = fixture.debugElement.nativeElement;
// attach the attribute selector of [disabled] and expect it to not be there
console.log(!component.triplegForm.valid); // ensure you see false here
expect(newCompiled.querySelector('#mat-toolbar__get-rate-button-id[disabled]')).toBeFalsy();
done();
});
});
it('should disable the button when Origin and Destination are invalid', (done) => {
const compiled = fixture.debugElement.nativeElement;
const originIdInput = compiled.querySelector(
".trip-origin-input"
);
originIdInput.value = "546";
originIdInput.dispatchEvent(new Event("input"));
const destinationIdInput = compiled.querySelector(
".trip-destination-input"
);
destinationIdInput.value = "NSGxx/43";
destinationIdInput.dispatchEvent(new Event("input"));
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(fixture.componentInstance.leg.originId).toBe('546');
expect(fixture.componentInstance.leg.destinationId).toBe('NSGxx/43');
// same logic here
console.log(!component.triplegForm.valid); // ensure you see true here
const newCompiled = fixture.debugElement.nativeElement;
expect(newCompiled.querySelector('#mat-toolbar__get-rate-button-id[disabled]')).toBeTruthy();
done();
});
});