单元测试登录组件



我想对登录组件进行单元测试。我正在使用反应性形式和角7。

我创建了后端假服务,我正在称之为该服务。我尝试了以下代码,但我收到以下错误:

TypeError:无法读取未定义的属性'debugelement'

如何调用登录方法以及如何订阅该值?

请任何人帮助我。

signin.component.html

     <form
        class="form"
        (ngSubmit)="onSubmit()"
        [formGroup]="signinForm"
        novalidate>
        <div fxLayout="row wrap" fxLayout.xs="column" fxLayoutAlign="center center">
          <div fxFlex="100" fxFlex.gt-md="25" fxFlex.gt-sm="25">
            <mat-card>
              <mat-card-header>
                <mat-card-title class="_mat-title">
                  <h5>Sign In</h5>
                </mat-card-title>
              </mat-card-header>
              <mat-card-content>
                <div
                  fxLayout="row wrap"
                  fxLayout.xs="column"
                  fxLayoutAlign="space-between stretch">
                  <div fxFlex="100" fxFlex.gt-md="100" fxFlex.gt-sm="100">
                    <mat-form-field>
                      <input
                        matInput
                        placeholder="Username(Email)"
                        formControlName="username"
                        value="{{username}}"
                        />
                      <mat-error
                        *ngIf="submitted &&
                        !signinForm.controls['username'].errors?.required &&
                        signinForm.controls['username'].errors?.email &&
                        signinForm.controls['username'].dirty">
                        Please enter a valid email address
                      </mat-error>
                      <mat-error
                        *ngIf="submitted &&
                        signinForm.controls['username'].errors?.required &&
                        signinForm.controls['username']">
                        Email is required
                      </mat-error>
                    </mat-form-field>
                  </div>
                  <div fxFlex="100" fxFlex.gt-md="100" fxFlex.gt-sm="100">
                    <mat-form-field>
                      <input
                        matInput
                        placeholder="Password"
                        type="password"
                        formControlName="password"
                        value="{{password}}"
                        />
                      <mat-error
                        *ngIf="submitted &&
                        signinForm.controls['password'].errors?.required &&
                        signinForm.controls['password']">
                        Password is required
                      </mat-error>
                    </mat-form-field>
                  </div>
                  <div fxFlex="100" fxFlex.gt-md="100" fxFlex.gt-sm="100">
                    <div class="_rem-me">
                      <mat-checkbox
                        color="primary"
                        class="_checkbox"
                        formControlName="ischeck">Remember me</mat-checkbox>
                    </div>
                    <div class="_forgot-link">
                      <a href="" class="_link">Forgot your username or password?</a>
                    </div>
                  </div>
                </div>
              </mat-card-content>
              <mat-card-actions>
                <div class="_button-row">
                  <button mat-raised-button color="primary">
                    Submit
                  </button>
                </div>
              </mat-card-actions>
            </mat-card>
          </div>
        </div>
      </form>
signin.component.ts 
import {Component, OnInit, Input }from '@angular/core'; 
import {ErrorStateMatcher }from '@angular/material/core'; 
import {
  FormControl, 
  FormGroup, 
  FormGroupDirective, 
  NgForm, 
  FormBuilder, 
  Validators
}from '@angular/forms'; 
import {SigninService }from '../../../services/signin/signin.service'; 
import {first }from 'rxjs/operators'; 
import {Router, ActivatedRoute }from '@angular/router'; 
/** Error when invalid control is dirty, touched, or submitted. */
@Component( {
  selector:'ap-signin', 
  templateUrl:'./signin.component.html', 
  styleUrls:['./signin.component.scss']
})
export class SigninComponent implements OnInit {
  // spinner
  pageLoaded:boolean; 
  @Input()diameter = 64; 
  @Input()strokeWidth = 7; 
  signinForm:FormGroup; 
  username:string; 
  password:string; 
  returnUrl:string; 
  submitted = false; 
  accessRequestForm = false; 
  //ischeck = true; 
  // matcher = new MyErrorStateMatcher();
  constructor(
    private signinService:SigninService, 
    private route:ActivatedRoute, 
    private router:Router, 
    private fb:FormBuilder
  ) {
    this.pageLoaded = false; 
    // redirect to dashboard if already signed in
    if (this.signinService.currentUserValue) {
      this.router.navigate(['/']); 
    }
  }
  ngOnInit() {
    setTimeout(() =>  {
      this.pageLoaded = true; 
    }, 500); 
    this.username = localStorage.getItem('username'); 
    this.password = localStorage.getItem('password'); 
    // Form validation
    this.formValidation(); 
    this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/'; 
  }
  // Form validation
  formValidation():void {
    this.signinForm = this.fb.group( {
      username:[null, [Validators.compose([Validators.required, Validators.email])]], 
      password:[null, [Validators.compose([Validators.required])]],
      ischeck: [false, Validators.required]
    }); 
  }
  get f() {
    return this.signinForm.controls; 
  }
  onSubmit() {
    this.submitted = true; 
    //alert(this.f.ischeck.value);
    if (this.signinForm.invalid) {
      return; 
    }
    this.pageLoaded = true; 
    this.signinService
      .signin(this.f.username.value, this.f.password.value)
      .pipe(first())
      .subscribe(
        data =>  {
          if (this.f.ischeck.value) {
          localStorage.setItem('username', this.f.username.value); 
          localStorage.setItem('password', this.f.password.value); 
          this.router.navigate([this.returnUrl]); 
          }else {
            localStorage.clear(); 
            this.router.navigate([this.returnUrl]); 
            }
        }, 
        err =>  {
          this.pageLoaded = false; 
        }); 
  }
}
signin.component.spec.ts
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { SigninComponent } from './signin.component';
import { RouterTestingModule } from '@angular/router/testing';
import { CoreModule } from '../../core.module';
import { FeaturesModule } from '../../../features/features.module';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; 
import { HttpClientModule } from '@angular/common/http';
import { SigninService, User } from '../../../services/signin/signin.service'
import { DebugElement } from '@angular/core';
import { By } from '@angular/platform-browser';

fdescribe('SigninComponent', () => {
  let signinComponent: SigninComponent;
  let signinService: SigninService;
  let fixture: ComponentFixture<SigninComponent>;
  let de: DebugElement;
  let el: HTMLElement;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule,
        CoreModule,
        FeaturesModule,
        BrowserAnimationsModule,
        HttpClientModule,
        FormsModule,
        ReactiveFormsModule
      ],
      declarations: [ ],
      providers: [SigninService],
    })
    .compileComponents();
  }));
  beforeEach(() => {
    const fixture = TestBed.createComponent(SigninComponent);
    signinComponent = fixture.componentInstance;
    //el = de.nativeElement;
    fixture.detectChanges();
  });
  it('should create', () => {
    expect(signinComponent).toBeTruthy();
  });

  it('should call auth signin method', () => {
    let loginElement: DebugElement;
    const debugElement = fixture.debugElement;
    let signinService = debugElement.injector.get(SigninService);
    let loginSpy = spyOn(signinService, 'signin').and.callThrough();
    loginElement = fixture.debugElement.query(By.css('form'));
    signinComponent.signinForm.controls['username'].setValue('test@hp.com');
    signinComponent.signinForm.controls['password'].setValue('12345');
    loginElement.triggerEventHandler('ngSubmit', null);
    expect(loginSpy).toHaveBeenCalledTimes(1);

  });
});

您在每个范围之前创建一个新的灯具变量。然后,您尝试访问IT块中的固定装置,但尚未将其分配给描述块中的固定装置。

 beforeEach(() => {
    const fixture = TestBed.createComponent(SigninComponent);  // <-- remove const
  });

最新更新