有人可以帮我了解如何对下面的应用程序组件进行单元测试吗?这是一个 Angular 2 应用程序。
应用程序
import { Component, OnInit } from '@angular/core';
import { Router, NavigationEnd, NavigationStart, NavigationCancel, NavigationError, RoutesRecognized } from '@angular/router';
import { DataService } from '../services/data';
@Component({
selector: 'app',
template: '<messages></messages><router-outlet></router-outlet>',
providers: [DataService]
})
export class AppComponent implements OnInit {
constructor(private router: Router, private data: DataService) {}
public ngOnInit(): void {
this.router.events.subscribe((event: NavigationStart | NavigationEnd | NavigationCancel | NavigationError | RoutesRecognized) => {
if (!(event instanceof NavigationEnd)) { return; }
document.body.scrollTop = 0;
});
window.addEventListener(
"offline", () => {
if (this.data.settings.offlineEnabled) {
this.data.toggleOffline();
this.data.displayMessage("Internet connection lost, switching to offline mode.", "failure")
} else {
this.data.displayMessage("Internet connection lost", "failure")
}
}, false,
);
}
}
到目前为止,我得到了什么:
app.spec.ts
import { TestBed, async, ComponentFixture } from '@angular/core/testing';
import { AppComponent } from './app'
import { RouterTestingModule } from '@angular/router/testing';
import { MessagesComponent } from './messages/messages';
import { DataService } from '../services/data';
/* Tests */
export class MockDataService {}
describe('Component: App', () => {
let mockData = new MockDataService();
let component: AppComponent;
let dataService: DataService;
let fixture: ComponentFixture<AppComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
AppComponent,
MessagesComponent
],
providers: [
{ provide: DataService, useValue: mockData }
]
}).compileComponents();
fixture = TestBed.createComponent(AppComponent);
component = fixture.componentInstance;
dataService = TestBed.get(DataService);
}));
it('should create the component', () => {
expect(component).toBeTruthy();
});
});
我收到错误: Failed: No provider for e!
但是,在我看来,我正在导入此组件实例化所需的所有内容。
我想知道这是否是 1( 要么RouterTestingModule
不知道router.events.subscribe
;或者,2(未定义window
。
有什么想法吗?
谢谢!
编辑 1:
似乎导致我问题的行是这样的:
@Component({
...,
...,
providers: [DataService]
})
看起来 Jasmine 正在将MockDataService
对象注入 app.component
构造函数中,但它没有为提供程序注入对象。 Jasmine正在提供具体的DataService
实施。
如何将MockDataService
注入app.component
的提供程序?
您的问题可能出现,因为您还在单元测试中声明了 MessagesComponent。Angular 将尝试更新此类的实例,如果您没有为 MessagesComponent 使用的服务注入模拟,那么这可能会导致您的错误。
但是,由于您正在对 AppComponent 进行单元测试,因此您不希望将消息组件添加到声明中,因为正如您所经历的那样,所有内容似乎都在 AppComponent 中工作,但组件的依赖项导致测试失败。解决此问题的最简单方法是将NO_ERRORS_SCHEMA添加到测试模块中,如下所示:
TestBed.configureTestingModule({
imports: [
RouterTestingModule
],
declarations: [
AppComponent
],
providers: [
{ provide: DataService, useValue: mockData }
],
schemas: [
NO_ERRORS_SCHEMA
]
}).compileComponents();
这将防止 Angular 编译器抱怨代码中的自定义 HTML 标记,例如标记。