繁体   English   中英

Jest Angular 测试用例

[英]Jest Angular Test case

我是编写测试用例的新手:

我有以下html文件:

<div class="momentum md">
  <div class="md-panel md-panel--full md-panel--form md-input--filled">
    <div class="md-panel__main">
      <div class="md-panel__image">
        <!--<img src="/images/cisco-webex-wordmark-black.svg">-->
        <div class="">
          <i class="icon icon-cisco-logo black"></i>
          <!--Login-->
        </div>
      </div>
      <div class="md-panel__title" translate="loginPage.email" style="font-size: 26px !important;;">Cisco Real-Time
        Monitor Tool
      </div>
      <form autocomplete="off" class="md-panel__form " name="loginForm" novalidate="" [formGroup]="loginForm"
            (ngSubmit)="onSubmit()">

        <md-input-container
          inputSize="small-12"
          label=""
        >
          <input
            mdInput
            name="username"
            formControlName="username"
            id="username"
            placeholder="Username"
          />
        </md-input-container>
        <div
          *ngIf="loginForm.get('username').invalid && (loginForm.get('username').dirty || loginForm.get('username').touched)"
          class="md-color--red-50">
          <div *ngIf="loginForm.get('username').errors.required"
               class="md-margin--s md-margin__horizontal--l validation-style">
            <md-icon name="clear" size="18"></md-icon>
            <span class="md-margin__left--s md-margin__top--xs">Please Enter Username</span>
          </div>
        </div>

        <md-input-container
          inputSize="small-12"
          label=""
        >
          <input
            type="password"
            mdInput
            name="password"
            formControlName="password"
            id="password"
            placeholder="Password"
          />
        </md-input-container>
        <div
          *ngIf="loginForm.get('password').invalid && (loginForm.get('password').dirty || loginForm.get('password').touched)"
          class="md-color--red-50">
          <div *ngIf="loginForm.get('password').errors.required"
               class="md-margin--s md-margin__horizontal--l validation-style">
            <md-icon  name="clear" size="18"></md-icon>
            <span class="md-margin__left--s md-margin__top--xs">Please Enter Password</span>
          </div>
        </div>

        <div class="md-panel__cta">
              <button md-button class="button-width" color="blue" alt="Submit Form" type="submit" [disabled]="!loginForm.valid" aria-label="Sign In"
              >
                  Sign In
              </button>
        </div>
        <div class="md-color--red-50 md-margin--s md-margin__horizontal--l">
          <span *ngIf="invalidCredentials">You've entered an incorrect username or password.</span>
          <span *ngIf="forbiddenUser">Access Denied</span>
        </div>
      </form>
    </div>
    <div class="md-panel__footer">
      <div class="footer__logo">
        <i class="icon icon-cisco-logo md-color--black"></i>
      </div>
      <div class="footer__copyright md-margin__top--s" style="font-size: 12px;">
        <div>
              <span>By using Cisco Services you accept the
                <a href="http://www.ciscospark.com/terms-of-service.html"
                   target="_blank">Terms of Service</a> and
                <a href="http://www.cisco.com/web/siteassets/legal/privacy.html" target="_blank">Privacy Statement</a>.</span>
          <span>© 2020 Cisco and/or affiliates. All rights reserved.</span>
        </div>

      </div>
    </div>
  </div>
</div>

ts文件:

import {Component, OnInit} from '@angular/core';
import {ActivatedRoute, Router} from '@angular/router';
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
import {AuthenticationService} from '../../../services/authentication.service';
import {HttpErrorResponse} from "@angular/common/http";
import _ from "lodash";

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss'],
})
export class LoginComponent implements OnInit {

  loginForm: FormGroup;
  private returnUrl: string;
  invalidCredentials = false;
  error = '';
  forbiddenUser = false;

  constructor(private formBuilder: FormBuilder,
              private route: ActivatedRoute,
              private router: Router,
              private authenticationService: AuthenticationService) {

  }

  username: string;
  password: string;

  ngOnInit() {
    this.loginForm = this.formBuilder.group({
      username: ['', Validators.required],
      password: ['', Validators.required]
    });
  }

  authenticate() {
    let code;
    let accessToken;
    let refreshToken;
    code = localStorage.getItem('code');
    if (code) {
      code = window.atob(code);
      accessToken = localStorage.getItem('accessToken');
      refreshToken = localStorage.getItem('refreshToken');
      if (accessToken && refreshToken) {
        accessToken = window.atob('accessToken');
        refreshToken = window.atob('refreshToken');
      }
    }
  }

  onSubmit() {
    this.invalidCredentials = false;
    this.forbiddenUser = false;

    this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';

    // stop here if form is invalid
    if (this.loginForm.invalid) {
      return;
    }

    this.authenticationService.login(this.loginForm.value.username, this.loginForm.value.password).subscribe({
      next: (data) => {
        this.router.navigateByUrl(this.returnUrl);
      },
      error: (errRes: HttpErrorResponse) => {
        if (errRes.status === 403) {
          if (errRes.error.ErrorMessage === "loginFailure") {
            this.invalidCredentials = true;
          } else if (_.has(errRes, 'error.username')) {
            this.forbiddenUser = true;
          }
        }
      }
  });
  }

}

我编写了以下.spec文件内容:

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { LoginComponent } from './login.component';
import {AuthenticationService} from '../../../services/authentication.service';
import { createComponent, Page, injectMocked } from '@webex/common/test-utils';


const MockAuthenticationService = {
  login: jest.fn(),
};

class LoginPage extends Page<LoginComponent> {
  constructor(fixture: ComponentFixture<LoginComponent>) {
    super(fixture);
  }

}

describe('LoginComponent', () => {
  let component: LoginComponent;
  let fixture: ComponentFixture<LoginComponent>;
  let page: LoginPage;
  let authServiceMock: any;
  let authenticationService: jest.Mocked<AuthenticationService>;

  beforeEach(async(() => {
    authServiceMock = {
      login: jest.fn()
    }
    TestBed.configureTestingModule({
      declarations: [ LoginComponent ],
      providers: [
        {
          provide: AuthenticationService,
          useValue: MockAuthenticationService,
        },
      ],
      imports: [
        FormsModule,
      ],
      schemas: [NO_ERRORS_SCHEMA],
    });

    authenticationService = injectMocked(AuthenticationService)
  }));

  beforeEach(() => {
    ({ fixture, component, page } = createComponent(LoginComponent, LoginPage));
    fixture.detectChanges();
  });

  it('should call login method', () => {
    expect(authenticationService.login).toHaveBeenCalledTimes(1);
  });
});

但它的抛出错误:

TypeError: Cannot read property 'login' of undefined

 

 it('should create', () => {
    expect(authenticationService.login).toHaveBeenCalledTimes(1);
                             ^
   });
});

 

我哪里错了? 请帮忙。

以这种方式尝试。 根据您的代码声明并初始化 mockInput 和 mockOutput。

const MockAuthenticationService = {
      login:(mockInput) => (mockOutput),
    
    };

第二件事是如果 authservice.login 在 onsubmit 函数中,你应该只为 onsubmit 函数而不是为 authServ.login 编写测试用例

例如。

    it('Test OnSubmit', () => {
        // your code
        //initializations
     component.onsubmit()
        // expect block
    })

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM