由于绑定到服务属性的 HTML NgModel 中的数据未更新,Angular 单元测试失败

问题描述 投票:0回答:1

我有一个带有

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();
    });
  });
angular unit-testing data-binding jasmine angular-ngmodel
1个回答
0
投票

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();
    });
  });
© www.soinside.com 2019 - 2024. All rights reserved.