[英]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.