我有一个带有
LoginPageComponent
和 email
字段的 password
,其值是 NgModel
绑定到 LoginServices
的属性 loginInfo
。 LoginPageComponent
还有 Login
按钮,当 loginInfo.isReadyToSubmit()
返回 false
(当电子邮件或密码为空时)时,该按钮将被禁用。
在
LoginPageComponent
的单元测试中,我想验证当 Login
返回 loginInfo.isReadyToSubmit()
时,true
按钮是否为 enabled。
我尝试了
dispatchEvent()
、detectChange()
和fixture.whenStable().then()
,但似乎没有任何效果。我应该如何继续?我很乐意接受我的代码其他方面的纠正/批评。
登录页面组件:
export class LoginPageComponent {
constructor(
protected loginServices: LoginServices,
private router: Router,
private toastServices: ToastServices
) {}
protected loginInfo: LoginInfo = this.loginServices.loginInfo;
登录页面组件 HTML:
<div class="route-container">
<spinner [isDisplayed]="loginServices.isLoggingIn()" />
<form #loginForm="ngForm" (ngSubmit)="onSubmit()">
<label>
Email <br />
<input type="email" [(ngModel)]="loginInfo.email" name="email" />
</label>
<br /><br />
<label>
Password <br />
<input type="password" [(ngModel)]="loginInfo.password" name="password" />
</label>
<br /><br />
<div class="center">
<button
type="submit"
[disabled]="!loginInfo.isReadyToSubmit() || loginServices.isLoggingIn()"
>
Login
</button>
</div>
</form>
</div>
登录服务:
export class LoginServices {
constructor(private http: HttpClient) {}
public loginInfo: LoginInfo = new LoginInfo('', '');
}
登录信息:
export class LoginInfo {
constructor(public email: string, public password: string) {}
public isReadyToSubmit(): boolean {
return this.email !== '' && this.password !== '';
}
}
LoginPageComponent 规格:
describe('LoginPageComponent', () => {
let component: LoginPageComponent;
let fixture: ComponentFixture<LoginPageComponent>;
let emailInput: HTMLInputElement;
let passwordInput: HTMLInputElement;
let loginButton: HTMLButtonElement;
let loginServices: LoginServices;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [
HttpClientModule,
ToastrModule.forRoot(),
MatProgressSpinnerModule,
],
declarations: [NgModel, NgForm, SpinnerComponent, LoginPageComponent],
providers: [{ provide: LoginServices }],
}).compileComponents();
fixture = TestBed.createComponent(LoginPageComponent);
component = fixture.componentInstance;
loginServices = TestBed.inject(LoginServices);
fixture.detectChanges();
const nativeElement: HTMLElement = fixture.nativeElement;
emailInput = nativeElement.querySelector('input[name="email"]')!;
passwordInput = nativeElement.querySelector('input[name="password"]')!;
loginButton = nativeElement.querySelector('button')!;
});
it('should enable Login button when there are email and password inputs', async () => {
const data = {
email: '[email protected]',
password: '123',
};
emailInput.value = data.email;
emailInput.dispatchEvent(new Event('input'));
fixture.detectChanges();
passwordInput.value = data.password;
passwordInput.dispatchEvent(new Event('input'));
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(loginButton.disabled).toBeFalse();
});
});
NgModel
就可以正常工作了,我们可以直接更新绑定到ngModel的属性,然后检查disabled。
it('should enable Login button when there are email and password inputs', async () => {
const data = {
email: '[email protected]',
password: '123',
};
component.loginInfo.email = data.email;
component.loginInfo.password = data.password;
fixture.detectChanges();
fixture.whenStable().then(() => {
expect(loginButton.disabled).toBeFalse();
});
});