在编写 Karma-Jasmine 单元测试用例时“错误: 没有路由器提供商”

我们已经建立了一个 angular2项目,在该项目中创建了一个模块(my-module) ,在该模块中使用以下 cmd 命令创建了一个组件(my-new-Component) :

ng new angular2test
cd angular2test
ng g module my-module
ng generate component my-new-component

在创建了设置和所有组件之后,我们在 angular2test 文件夹中从 cmd 运行 ng test命令。

下面的文件是 my-new-Component. Component. ts 文件 :

import { Component, OnInit } from '@angular/core';
import { Router, Routes, RouterModule } from '@angular/router';
import { DummyService } from '../services/dummy.service';


@Component({
selector: 'app-my-new-component',
templateUrl: './my-new-component.component.html',
styleUrls: ['./my-new-component.component.css']
})
export class MyNewComponentComponent implements OnInit {


constructor(private router : Router, private dummyService:DummyService) { }


ngOnInit() {
}
redirect() : void{
//this.router.navigate(['/my-module/my-new-component-1'])
}
}

下面的文件是我们的 my-new-Component. Component ent.spec.ts 文件 :

/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';


import { RouterTestingModule } from '@angular/router/testing';
import {NgbModule} from '@ng-bootstrap/ng-bootstrap';
import { DummyService } from '../services/dummy.service';


import { MyNewComponentComponent } from './my-new-component.component';


describe('MyNewComponentComponent', () => {
let component: MyNewComponentComponent;
let fixture: ComponentFixture<MyNewComponentComponent>;


beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule, NgbModule.forRoot(), DummyService],
declarations: [ MyNewComponentComponent ]
})
.compileComponents();
}));


beforeEach(() => {
fixture = TestBed.createComponent(MyNewComponentComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});


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

在运行 ng test 命令时,我们得到了下面的 cmd 错误:

    Chrome 54.0.2840 (Windows 7 0.0.0): Executed 1 of 1 (1 FAILED) ERROR (0.593 secs / 2.007 secs)
Chrome 54.0.2840 (Windows 7 0.0.0) MyNewComponentComponent should create FAILED
Failed: Unexpected value 'DummyService' imported by the module 'DynamicTestModule'
Error: Unexpected value 'DummyService' imported by the module 'DynamicTestModule'

我们已经更新了组件文件和规范文件。请在下面的代码片段中找到。

下面的文件是 my-new-Component. Component. ts 文件 :

import { Component, OnInit } from '@angular/core';
import { Router, Routes, RouterModule } from '@angular/router';
import { DummyService } from '../services/dummy.service';


@Component({
selector: 'app-my-new-component',
templateUrl: './my-new-component.component.html',
styleUrls: ['./my-new-component.component.css']
})
export class MyNewComponentComponent implements OnInit {


constructor(private router : Router, private dummyService:DummyService, public fb: FormBuilder) {
super(fb);
}


ngOnInit() {
}
redirect() : void{
//this.router.navigate(['/my-module/my-new-component-1'])
}
}

下面的文件是我们的 my-new-Component. Component ent.spec.ts 文件 :

/* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';
import { FormsModule, FormGroup, FormBuilder, Validators, ReactiveFormsModule} from '@angular/forms';
import { SplitPipe } from '../../common/pipes/string-split.pipe';
import { RouterTestingModule } from '@angular/router/testing';
import { DummyService } from '../services/dummy.service';
import { MyNewComponentComponent } from './my-new-component.component';


describe('MyNewComponentComponent', () => {
let component: MyNewComponentComponent;
let fixture: ComponentFixture<MyNewComponentComponent>;


beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule, DummyService ,HttpModule, FormBuilder],
declarations: [ MyNewComponentComponent, SplitPipe]
})
.compileComponents();
}));


beforeEach(() => {
fixture = TestBed.createComponent(MyNewComponentComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});


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

但是在运行 ng 测试命令时,我们会得到以下错误。

09 12 2016 09:13:48.987:WARN [karma]: No captured browser, open http://localhost:9876/
09 12 2016 09:13:49.008:INFO [karma]: Karma v1.2.0 server started at http://localhost:9876/
09 12 2016 09:13:49.010:INFO [launcher]: Launching browser Chrome with unlimited concurrency
09 12 2016 09:13:49.420:INFO [launcher]: Starting browser Chrome
09 12 2016 09:13:58.642:INFO [Chrome 54.0.2840 (Windows 7 0.0.0)]: Connected on socket /#QZ9LSSUVeK6KwNDlAAAA with id 46830907
Failed: Unexpected value 'FormBuilder' imported by the module 'DynamicTestModule'
Error: Unexpected value 'FormBuilder' imported by the module 'DynamicTestModule'
130165 次浏览

在设置测试模块时,需要导入 RouterTestingModule 路由测试模块

  /* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';


import { RouterTestingModule } from '@angular/router/testing';


import { MyNewComponentComponent } from './my-new-component.component';


describe('MyNewComponentComponent', () => {
let component: MyNewComponentComponent;
let fixture: ComponentFixture<MyNewComponentComponent>;


beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [ MyNewComponentComponent ]
})
.compileComponents();
}));


beforeEach(() => {
fixture = TestBed.createComponent(MyNewComponentComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});


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

编辑: 使用模拟 DummyService 的示例

  /* tslint:disable:no-unused-variable */
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { DebugElement } from '@angular/core';


import { RouterTestingModule } from '@angular/router/testing';


import { MyNewComponentComponent } from './my-new-component.component';


// import the service
import { DummyService } from '../dummy.service';


// mock the service
class MockDummyService extends DummyService {
// mock everything used by the component
};


describe('MyNewComponentComponent', () => {
let component: MyNewComponentComponent;
let fixture: ComponentFixture<MyNewComponentComponent>;


beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule],
declarations: [MyNewComponentComponent],
providers: [{
provide: DummyService,
useClass: MockDummyService
}]
})
.compileComponents();
}));


beforeEach(() => {
fixture = TestBed.createComponent(MyNewComponentComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});


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

为 configureTestingModule testCase 添加 RouterTestingModule

= = > 导入: [ RouterTestingModule ] ,

import {RouterTestingModule} from '@angular/router/testing';


beforeEach(() => {
TestBed.configureTestingModule({
imports: [RouterTestingModule], // <====
providers: [],
declarations: [],
});
});

我得到了同样的错误,我想分享我的解决方案,以帮助他人

我在因果报应中得到的错误

error properties: Object({ ngTempTokenPath: null, ngTokenPath: [ 'RouterModule', 'Router', 'Function', 'Function' ] })
NullInjectorError: R3InjectorError(DynamicTestModule)[RouterModule -> Router -> Function -> Function]:
NullInjectorError: No provider for Function!

库存视图组件

@Component({
selector: 'app-inventory-view',
templateUrl: './inventory-view.component.html',
styleUrls: ['./inventory-view.component.scss'],
animations: []
})
export class InventoryViewComponent implements OnInit, AfterViewInit, OnDestroy {


constructor(
public router: Router, // <--- here was the problem
public activatedRoute: ActivatedRoute
) { }


在我的测试文件里

库存-视图。组件

import { HttpClientModule } from '@angular/common/http';
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { ActivatedRoute, convertToParamMap, Router } from '@angular/router';


const ActivatedRouteSpy = {
snapshot: {
paramMap: convertToParamMap({
some: 'some',
else: 'else',
})
},
queryParamMap: of(
convertToParamMap({
some: 'some',
else: 'else',
})
)
};


const RouterSpy = jasmine.createSpyObj(
'Router',
['navigate']
);


describe('InventoryViewComponent', () => {
let component: InventoryViewComponent;
let fixture: ComponentFixture<InventoryViewComponent>;


beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
imports: [
HttpClientModule,
RouterTestingModule,
],
declarations: [ InventoryViewComponent ],
providers: [
{ provide: ActivatedRoute,   useValue: ActivatedRouteSpy    },
{ provide: Router,           useValue: RouterSpy            }
]
})
.compileComponents();
}));


beforeEach(waitForAsync(() => {
fixture = TestBed.createComponent(InventoryViewComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));


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