gpt4 book ai didi

未定义的 Angular 2 Jasmine 不是对象

转载 作者:太空狗 更新时间:2023-10-29 19:30:15 26 4
gpt4 key购买 nike

我正在为 Angular 2 中的 NavBar 组件编写单元测试。我模拟了路由器,它通过了我的所有测试;但是,我创建了一个服务来为路由设置事件类,这导致我的单元测试失败并出现错误:

undefined is not an object (evaluating 'this.router.url.substring')

导航服务

import { Injectable } from '@angular/core';
import { Router, RouterModule } from '@angular/router';

@Injectable()
export class NavActiveService {
constructor(private router: Router) {

}

homeActive() {
if (this.router.url === '/') {
return '#0fecdb';
}
else {
return '#00f';
}
}

loginActive() {
if (this.router.url.substring(0,6) === '/login') {
return '#0fecdb';
}
else {
return '#00f';
}
}

uploadActive() {
if (this.router.url.substring(0,7) === '/upload') {
return '#0fecdb';
}
else {
return '#00f';
}
}

aboutActive() {
if (this.router.url.substring(0,5) === '/about') {
return '#0fecdb';
}
else {
return '#00f';
}
}

contactActive() {
if (this.router.url.substring(0,7) === '/contact') {
return '#0fecdb';
}
else {
return '#00f';
}
}

four04Active() {
if (this.router.url === '/**') {
return '#0fecdb';
}
else {
return '#00f';
}
}
}

导航栏组件

import { Component } from '@angular/core';
import { Router } from '@angular/router';
import { NavActiveService } from '../../../services/navactive.service';
import { GlobalEventsManager } from '../../../services/GlobalEventsManager';

@Component({
moduleId: module.id,
selector: 'my-navbar',
templateUrl: 'navbar.component.html',
styleUrls:['navbar.component.css'],
providers: [NavActiveService]
})
export class NavComponent {
showNavBar: boolean = true;

constructor(private router: Router,
private navactiveservice:NavActiveService,
private globalEventsManager: GlobalEventsManager){

this.globalEventsManager.showNavBar.subscribe((mode:boolean)=>{
this.showNavBar = mode;
});

}

}

导航栏 HTML

<div *ngIf="showNavBar">
<nav class="navbar navbar-fixed-top navbar-light bg-faded">
<button class="navbar-toggler hidden-sm-up" type="button" data-toggle="collapse" data-target="#navbar">
&#9776;
</button>
<div class="collapse navbar-toggleable-xs" id="navbar">
<div class="container">
<a class="navbar-brand" [routerLink]="'/'">My App</a>
<ul class="nav navbar-nav navbar-right">
<li class="nav-item" >
<a class="nav-link" [routerLink]="'/'" [style.backgroundColor]="this.navactiveservice.homeActive()" > <i class="fa fa-home"></i> Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item" >
<a class="nav-link" [routerLink]="'/upload'" [style.backgroundColor]="this.navactiveservice.uploadActive()" > <i class="fa fa-upload"></i> Upload </a>
</li>
<li class="nav-item" >
<a class="nav-link" [routerLink]="'/about'" [style.backgroundColor]="this.navactiveservice.aboutActive()" > <i class="fa fa-bar-chart"> </i> Tracking Data</a>
</li>
<li class="nav-item" >
<a class="nav-link" [routerLink]="'/login'" [style.backgroundColor]="this.navactiveservice.loginActive()" > <i class="fa fa-user"></i> Logout</a>
</li>
</ul>
</div>
</div>
</nav>
</div>

导航栏单元测试

import { ComponentFixture, TestBed, async  } from '@angular/core/testing';
import { NavComponent } from './navbar.component';
import { DebugElement } from '@angular/core';
import { By } from '@angular/platform-browser';
import { RouterLinkStubDirective, RouterOutletStubComponent } from '../../../../test/router-stubs';
import { Router } from '@angular/router';
import { GlobalEventsManager } from '../../../services/GlobalEventsManager';
import { NavActiveService } from '../../../services/navactive.service';
import { RouterModule } from '@angular/router';
import { SharedModule } from '../shared.module';


export function main() {
let comp: NavComponent;
let fixture: ComponentFixture<NavComponent>;
let mockRouter:any;
class MockRouter {
//noinspection TypeScriptUnresolvedFunction
navigate = jasmine.createSpy('navigate');
}

describe('Navbar Componenet', () => {

beforeEach( async(() => {
mockRouter = new MockRouter();
TestBed.configureTestingModule({
imports: [ SharedModule ]
})

// Get rid of app's Router configuration otherwise many failures.
// Doing so removes Router declarations; add the Router stubs
.overrideModule(SharedModule, {
remove: {
imports: [ RouterModule ],

},
add: {
declarations: [ RouterLinkStubDirective, RouterOutletStubComponent ],
providers: [ { provide: Router, useValue: mockRouter }, GlobalEventsManager, NavActiveService ],
}
})

.compileComponents()

.then(() => {
fixture = TestBed.createComponent(NavComponent);
comp = fixture.componentInstance;
});
}));

tests();
});


function tests() {
let links: RouterLinkStubDirective[];
let linkDes: DebugElement[];

beforeEach(() => {
// trigger initial data binding
fixture.detectChanges();

// find DebugElements with an attached RouterLinkStubDirective
linkDes = fixture.debugElement
.queryAll(By.directive(RouterLinkStubDirective));

// get the attached link directive instances using the DebugElement injectors
links = linkDes
.map(de => de.injector.get(RouterLinkStubDirective) as RouterLinkStubDirective);
});

it('can instantiate it', () => {
expect(comp).not.toBeNull();
});

it('can get RouterLinks from template', () => {
expect(links.length).toBe(5, 'should have 5 links');
expect(links[0].linkParams).toBe( '/', '1st link should go to Home');
expect(links[1].linkParams).toBe('/', '2nd link should go to Home');
});

it('can click upload link in template', () => {
const uploadLinkDe = linkDes[2];
const uploadLink = links[2];

expect(uploadLink.navigatedTo).toBeNull('link should not have navigated yet');

uploadLinkDe.triggerEventHandler('click', null);
fixture.detectChanges();

expect(uploadLink.navigatedTo).toBe('/upload');
});
}
}

我如何模拟 navActiveService 以便我的测试成功通过?

最佳答案

在您的 NavActiveService 中,您正在使用 this.router.url.substring(0,7),但是您的 Router stub 没有没有 url 属性。它只有一个 navigate 函数。

也许对于每个测试,您可能只想设置 url 的值。

mockRouter.url = '/contact'

或者如果它不需要为测试而更改,则只需在声明时添加它即可。

class MockRouter {
url = '/';
navigate = jasmine.createSpy('navigate');
}

关于未定义的 Angular 2 Jasmine 不是对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40771575/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com