2

내 NavBar 구성 요소의 단위 테스트를 각도 2로 작성했습니다. 라우터를 조롱하고 모든 테스트를 통과했습니다. 그러나, 나는 경로의 활성 클래스를 설정하는 서비스를 생성하고이 오류와 함께 실패 할 내 단위 테스트의 원인 :각도 2 재스민 실패 미정입니다. 객체가 아닙니다.

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

NavActive 서비스

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'; 
     } 
    } 
} 

Navbar의 구성 요소

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; 
    }); 

    } 

} 

navbar 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> 

Navbar의 단위 테스트 내 검사를 성공적으로 통과하도록 나는 navActiveService을 조롱 수있는 방법

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에서

답변

1

, 당신은 this.router.url.substring(0,7)를 사용하고 있지만 Router 스텁은 url 속성이 없습니다. 단일 navigate 기능 만 있습니다.

아마도 각 테스트마다 url의 값을 설정하기 만하면됩니다.

mockRouter.url = '/contact' 

테스트를 위해 변경할 필요가없는 경우 선언 할 때 추가하십시오.

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

문제가 발생했습니다. 감사합니다. – Bhetzie

관련 문제