使用Jasmine -Karma进行Angular 9单元测试

问题描述

如何为我的login.component.ts编写单元测试 我需要用于表单提交的单元测试代码。除了表格提交以外,我的案件都是正确的。我1失败,6成功。 实际上,我是单元测试的新手,并且对单元测试的了解有限。

这是我当前的代码 login.component.ts

import { Component,OnInit } from "@angular/core";
import { Router } from "@angular/router";
import { FormBuilder,FormGroup,Validators } from "@angular/forms";
import { AuthService } from "../shared/services/auth.service";
import { MatSnackBar } from "@angular/material/snack-bar";

@Component({
  selector: "app-login",templateUrl: "./login.component.html",styleUrls: ["./login.component.scss"],})
export class LoginComponent implements OnInit {
  // initialisation of variables
  loginForm: FormGroup;
  submitted = false;
  constructor(
    private router: Router,private fb: FormBuilder,private authService: AuthService,private _snackBar: MatSnackBar
  ) {
    this.loginForm = this.fb.group({
      email: ["",Validators.required],password: ["",});
  }

  ngOnInit() {
      if (this.authService.getToken()) {

        this.router.navigate(["/dashboard"]);
      }

  }

  get f() {
    return this.loginForm.controls;
  }

  // Login button function
  // @author : Iqbal k k

  onLogin() {
    const data = {
      email: this.loginForm.value.email,password: this.loginForm.value.password,};
    this.submitted = true;
    this.authService.logIn(data).subscribe(
      (res: any) => {
        localStorage.setItem("access_token",res.success.data.token);
        localStorage.setItem("user_name",res.success.data.name);
        localStorage.setItem("user_id",res.success.data.userId);
        localStorage.setItem("user_email",res.success.data.email);
        this.router.navigate(["/dashboard"]);
      },(error) => {
        this.router.navigate(["/login"]);
        const msg = error["error"].error.message;
        this._snackBar.open(msg,"",{
          duration: 2000,verticalPosition: "bottom",});
      }
    );
  }
}

login.component.spec.ts

import { HttpClientTestingModule } from '@angular/common/http/testing';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { MatDialogModule } from '@angular/material/dialog';
import { async,ComponentFixture,TestBed,fakeAsync } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { LoginComponent } from './login.component';
import { ReactiveFormsModule,FormsModule } from "@angular/forms";
import { AuthService } from "../shared/services/auth.service";
import { User } from '../shared/models/user';
//import { By } from 'protractor';
import { By } from '@angular/platform-browser';

describe('LoginComponent',() => {
  let component: LoginComponent;
  let fixture: ComponentFixture<LoginComponent>;
  let authService: AuthService;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [RouterTestingModule,FormsModule,ReactiveFormsModule,HttpClientTestingModule,MatDialogModule,MatSnackBarModule],declarations: [LoginComponent],providers:[AuthService]
    }).compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(LoginComponent);
    component = fixture.componentInstance;
     // UserService provided to the TestBed
     authService = TestBed.get(AuthService); 

    fixture.detectChanges();
  });

    it('needsLogin returns true when the user has not been authenticated',() => {
        spyOn(authService,'logIn').and.returnValue(false);
        expect(component.onLogin()).toBeTruthy();
        expect(authService.logIn).toHaveBeenCalled();
    });

    it('needsLogin returns false when the user has been authenticated','logIn').and.returnValue(true);
        expect(component.onLogin()).toBeFalsy();
        expect(authService.logIn).toHaveBeenCalled();
    });

  it('should create',() => {
    expect(component).toBeTruthy();
  });

  
  it('Should set submitted to true',async(() => {
    component.onLogin();
    expect(component.onLogin).toBeTruthy();

 }));

 it('Should call the OnSubmit method',() =>{ fakeAsync(() =>{
   fixture.detectChanges();
   spyOn(component,'onLogin');
   const el=fixture.debugElement.query(By.css('Login')).nativeElement;
   el.click();
   expect(component.onLogin).toHaveBeenCalledTimes(0);
 })

 });

 it('Form should be invalid',async(()=> {
   component.loginForm.controls['email'].setValue('');
   component.loginForm.controls['password'].setValue('');
   expect(component.loginForm.valid).toBeFalsy();
 }));

 it('Form should be valid',async(()=> {
   component.loginForm.controls['email'].setValue('admin');
   component.loginForm.controls['password'].setValue('admin123');
   expect(component.loginForm.valid).toBeTruthy();
 }));

 //test form submission
  it('submitting a form emits a user',() => {
    expect(component.loginForm.valid).toBeFalsy();
    component.loginForm.controls['email'].setValue("flerri@gmail.com");
    component.loginForm.controls['password'].setValue("12345");
    expect(component.loginForm.valid).toBeTruthy();

    let user: User;
    // Subscribe to the Observable and store the user in a local variable.
    this.service.logIn.subscribe((value) => user = value);

    // Trigger the login function
    component.onLogin();

    // Now we can check to make sure the emitted value is correct
    expect(user.email).toBe("flerri@gmail.com");
    console.log(user.email);
    expect(user.password).toBe("12345");
  });
});

auth.service.ts

import { FLERRI_URL } from "./../../app.constant";
import { Injectable } from "@angular/core";
import { User } from "../models/user";
import { Observable,throwError } from "rxjs";
import { catchError,map } from "rxjs/operators";
import {
  HttpClient,HttpHeaders,HttpErrorResponse,} from "@angular/common/http";
import { Router } from "@angular/router";
import {MatDialog} from '@angular/material/dialog';


@Injectable({
  providedIn: "root",})
export class AuthService {
  endpoint = FLERRI_URL;
  headers = new HttpHeaders().set("Content-Type","application/json");
  currentUser = {};

  constructor(private http: HttpClient,public router: Router,private dialogRef: MatDialog ) {}

  // Login
  // @author : Iqbal k k
  logIn(user) {
    return this.http.post<any>(`${this.endpoint}login`,user);
  }

  // Get Tocken from local storage
  // @author : Iqbal k k
  getToken() {
    return localStorage.getItem("access_token");
  }

  get isLoggedIn(): boolean {
    const authToken = localStorage.getItem("access_token");
    return authToken !== null ? true : false;
  }

  // Logout
  // @author : Iqbal k k
  doLogout() {
    this.dialogRef.closeAll();
    const removeToken = localStorage.removeItem("access_token");
    if (removeToken == null) {
      this.router.navigate(["login"]);
    }
  }

  // User profile
  // getUserProfile(id): Observable<any> {
  //   let api = `${this.endpoint}/user-profile/${id}`;
  //   return this.http.get(api,{ headers: this.headers }).pipe(
  //     map((res: Response) => {
  //       return res || {};
  //     }),//     catchError(this.handleError)
  //   );
  // }

  // Error
  handleError(error: HttpErrorResponse) {
    let msg = "";
    if (error.error instanceof ErrorEvent) {
      // client-side error
      msg = error.error.message;
    } else {
      // server-side error
      msg = `Error Code: ${error.status}\nMessage: ${error.message}`;
    }
    return throwError(msg);
  }
}

如何为该组件编写测试以使0失败? 除了单元测试之外,我还需要关心什么?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...