簡體   English   中英

單元測試登錄組件

[英]unit testing login component

我想對登錄組件進行單元測試。 我正在使用反應形式和Angular 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);



  });

});

您可以在每個范圍之前創建一個新的fixture變量。 然后,您嘗試訪問it塊中的燈具,但尚未在describe塊中將其分配給燈具。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM