Angular 5 - Jasmine / Karma 测试用例:通过输入验证启用/禁用按钮
Angular 5 - Jasmine / Karma Test Case: Button Enable / Disable by input validation
我对 Angular 及其测试框架 Jasmine 和 Karma 还是个新手。
我一直在测试一个按钮,以确保当用户输入正确的信息时,它始终处于启用状态;主要是在表单组验证控件激活按钮之前过早调用 .toBeFalsy() 。 现在,出于保密原因,我不能分享我的代码到底是什么,也不能分享问题的完整描述,但我可以给出的一个 public 示例是注册页面Trello 显示 here.
最初,表单是空的,“创建新帐户”按钮被禁用,用户无法点击它来创建帐户。当用户在这三个文本字段中输入有效信息时,按钮将被激活,让用户将请求发送到 Trello 的后端以注册帐户。
比方说,我是 Trello 的一名开发人员,他想测试这个案例,当用户填写正确的信息时启用按钮,使用带有 Angular 的 Jasmine 和 Karma 5 组件作为布局、功能和外观的组件。我要解决的问题是“创建新帐户”按钮的状态已更改为启用的时间,因为基本上我正在测试以确保在正确填写表格后,该按钮被激活并且 . toBeFalsy() 断言通过。
我的那个测试用例的代码,以及该用例所在的测试套件,将在 create-account.component.spec.ts 中如下所示。 (假设保存 Trello 帐户页面的 MVC 的组件称为 CreateAccountComponent,并且组件的所有属性都在 create-account.component.ts 中声明)
// Import all the required components for the test.
// Some are redundant for this case, but are useful for testing the whole frontend page anyway.
import { async, ComponentFixture, TestBed, getTestBed } from '@angular/core/testing';
import { CreateAccountComponent } from './create-account.component';
import { Validators, AbstractControl, ValidatorFn, Validator, FormsModule, FormGroup, FormControl, ReactiveFormsModule } from '@angular/forms';
import { HttpHeaders, HttpRequest, HttpResponse, HttpInterceptor, HTTP_INTERCEPTORS, HttpClient, HttpErrorResponse, HttpClientModule } from '@angular/common/http';
import { Router } from "@angular/router";
import { RouterTestingModule } from '@angular/router/testing';
import { By } from '@angular/platform-browser'
describe(‘Trello Create Account’, () => {
// Test unit fields
let createAccountPageComponent: CreateAccountComponent;
let createAccountPage: ComponentFixture< CreateAccountComponent >;
let rootElementOfComponent: any;
let root_Debug_Element_Of_Component: any;
// Create and set up the testing module.
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [CreateAccountComponent],
imports: [ ReactiveFormsModule , HttpClientModule, RouterTestingModule ]
})
.compileComponents();
}));
// Before each test case, initialize the suite fields as needed.
beforeEach(() => {
createAccountPage = TestBed.createComponent(CreateAccountComponent);
createAccountPageComponent = createAccountPage.componentInstance;
createAccountPage.detectChanges();
rootElementOfComponent = createAccountPage.nativeElement;
rootDebugElementOfComponent = createAccountPage.debugElement;
});
it('should have the Create New Account when the form fields are valid, () => {
// Watch for the ngModelChange function call when the value of the password, e-mail address
// and name change.
spyOn(createAccountPageComponent, 'updateCreateNewAccount');
// Simulate the user entering their full name.
rootDebugElementOfComponent query(By.css('#fullNameField')).nativeElement.dispatchEvent(new Event('input'));
createAccountPageComponent.createAccountPageForm.get(‘fullName').markAsTouched();
createAccountPageComponent.accountFullName= "Anonymous Person";
// Simulate the user entering their e-mail address.
rootDebugElementOfComponent query(By.css('#emailAddressField')).nativeElement.dispatchEvent(new Event('input'));
createAccountPageComponent.createAccountPageForm.get(‘emailAddress').markAsTouched();
createAccountPageComponent accountEmailAddress = "anonymous@person.com";
// Simulate the user entering a password.
rootDebugElementOfComponent query(By.css('#passwordField')).nativeElement.dispatchEvent(new Event('input'));
createAccountPageComponent.createAccountPageForm.get(‘password’).markAsTouched();
createAccountPageComponent.accountPassword = "anonymous";
// Update the new account button and have the screenshot track for changes.
createAccountPageComponent.updateNewAccountButton();
createAccountPage.detectChanges();
// Once the changes are detected, test to see if the 'Create New Account' button is enabled.
createAccountPage.whenStable().then(() => {
expect(rootElementOfComponent.querySelector('#createNewAccountButton').disabled).toBeFalsy();
expect(rootDebugElementOfComponent.query(By.css('#createNewAccountButtonButton')).nativeElement.disabled).toBeFalsy();
});
});
});
但是,这不起作用,因为 then 函数调用主体中的两个 expect 语句抛出错误,指出禁用属性实际上是 true。
我确实四处寻找是否有办法解决这个问题,包括其他 Whosebug 问题 。但很遗憾,我没有运气。
我最初的猜测是 whenStable() 函数和 then 函数调用的主体是异步执行的,但我很确定我错了。
我该怎么办?
看来我是一只傻老熊
与我一起工作的人检查了代码并指出了一些我不知道的事情:spyOn 函数应该仅 在测试函数调用时使用使用模拟对象隔离 。所以我把它注释掉了,测试用例按预期工作。
我想发生的事情是我的组件对象,它附加到模板,是 actua
我对 Angular 及其测试框架 Jasmine 和 Karma 还是个新手。
我一直在测试一个按钮,以确保当用户输入正确的信息时,它始终处于启用状态;主要是在表单组验证控件激活按钮之前过早调用 .toBeFalsy() 。 现在,出于保密原因,我不能分享我的代码到底是什么,也不能分享问题的完整描述,但我可以给出的一个 public 示例是注册页面Trello 显示 here.
最初,表单是空的,“创建新帐户”按钮被禁用,用户无法点击它来创建帐户。当用户在这三个文本字段中输入有效信息时,按钮将被激活,让用户将请求发送到 Trello 的后端以注册帐户。
比方说,我是 Trello 的一名开发人员,他想测试这个案例,当用户填写正确的信息时启用按钮,使用带有 Angular 的 Jasmine 和 Karma 5 组件作为布局、功能和外观的组件。我要解决的问题是“创建新帐户”按钮的状态已更改为启用的时间,因为基本上我正在测试以确保在正确填写表格后,该按钮被激活并且 . toBeFalsy() 断言通过。
我的那个测试用例的代码,以及该用例所在的测试套件,将在 create-account.component.spec.ts 中如下所示。 (假设保存 Trello 帐户页面的 MVC 的组件称为 CreateAccountComponent,并且组件的所有属性都在 create-account.component.ts 中声明)
// Import all the required components for the test.
// Some are redundant for this case, but are useful for testing the whole frontend page anyway.
import { async, ComponentFixture, TestBed, getTestBed } from '@angular/core/testing';
import { CreateAccountComponent } from './create-account.component';
import { Validators, AbstractControl, ValidatorFn, Validator, FormsModule, FormGroup, FormControl, ReactiveFormsModule } from '@angular/forms';
import { HttpHeaders, HttpRequest, HttpResponse, HttpInterceptor, HTTP_INTERCEPTORS, HttpClient, HttpErrorResponse, HttpClientModule } from '@angular/common/http';
import { Router } from "@angular/router";
import { RouterTestingModule } from '@angular/router/testing';
import { By } from '@angular/platform-browser'
describe(‘Trello Create Account’, () => {
// Test unit fields
let createAccountPageComponent: CreateAccountComponent;
let createAccountPage: ComponentFixture< CreateAccountComponent >;
let rootElementOfComponent: any;
let root_Debug_Element_Of_Component: any;
// Create and set up the testing module.
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [CreateAccountComponent],
imports: [ ReactiveFormsModule , HttpClientModule, RouterTestingModule ]
})
.compileComponents();
}));
// Before each test case, initialize the suite fields as needed.
beforeEach(() => {
createAccountPage = TestBed.createComponent(CreateAccountComponent);
createAccountPageComponent = createAccountPage.componentInstance;
createAccountPage.detectChanges();
rootElementOfComponent = createAccountPage.nativeElement;
rootDebugElementOfComponent = createAccountPage.debugElement;
});
it('should have the Create New Account when the form fields are valid, () => {
// Watch for the ngModelChange function call when the value of the password, e-mail address
// and name change.
spyOn(createAccountPageComponent, 'updateCreateNewAccount');
// Simulate the user entering their full name.
rootDebugElementOfComponent query(By.css('#fullNameField')).nativeElement.dispatchEvent(new Event('input'));
createAccountPageComponent.createAccountPageForm.get(‘fullName').markAsTouched();
createAccountPageComponent.accountFullName= "Anonymous Person";
// Simulate the user entering their e-mail address.
rootDebugElementOfComponent query(By.css('#emailAddressField')).nativeElement.dispatchEvent(new Event('input'));
createAccountPageComponent.createAccountPageForm.get(‘emailAddress').markAsTouched();
createAccountPageComponent accountEmailAddress = "anonymous@person.com";
// Simulate the user entering a password.
rootDebugElementOfComponent query(By.css('#passwordField')).nativeElement.dispatchEvent(new Event('input'));
createAccountPageComponent.createAccountPageForm.get(‘password’).markAsTouched();
createAccountPageComponent.accountPassword = "anonymous";
// Update the new account button and have the screenshot track for changes.
createAccountPageComponent.updateNewAccountButton();
createAccountPage.detectChanges();
// Once the changes are detected, test to see if the 'Create New Account' button is enabled.
createAccountPage.whenStable().then(() => {
expect(rootElementOfComponent.querySelector('#createNewAccountButton').disabled).toBeFalsy();
expect(rootDebugElementOfComponent.query(By.css('#createNewAccountButtonButton')).nativeElement.disabled).toBeFalsy();
});
});
});
但是,这不起作用,因为 then 函数调用主体中的两个 expect 语句抛出错误,指出禁用属性实际上是 true。
我确实四处寻找是否有办法解决这个问题,包括其他 Whosebug 问题
我最初的猜测是 whenStable() 函数和 then 函数调用的主体是异步执行的,但我很确定我错了。
我该怎么办?
看来我是一只傻老熊
与我一起工作的人检查了代码并指出了一些我不知道的事情:spyOn 函数应该仅 在测试函数调用时使用使用模拟对象隔离 。所以我把它注释掉了,测试用例按预期工作。
我想发生的事情是我的组件对象,它附加到模板,是 actua