【发布时间】:2021-06-06 13:48:59
【问题描述】:
我正在尝试对需要解析器、路由器和激活路由作为依赖项的组件进行单元测试。我尝试使用 RouterTestingModule 并模拟我的解析器以在测试模块中提供它们,但它似乎对组件实例的创建有一些副作用。
这是我的组件的代码:
History.component.ts
import { Component, OnDestroy, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Subscription } from 'rxjs';
import { Transaction } from '../models/transaction.model';
@Component({
selector: 'app-history',
templateUrl: './history.component.html',
styleUrls: ['./history.component.scss']
})
export class HistoryComponent implements OnInit, OnDestroy {
history: Transaction[] = [];
selectedTransaction: Transaction | undefined;
subscription: Subscription = new Subscription();
constructor(
private route: ActivatedRoute,
private router: Router,
) { }
ngOnInit(): void {
this.history = this.route.snapshot.data.history;
const routeSubscription = this.route.params.subscribe((params) => {
if (params.id) {
this.setSelectedTransaction(+params.id);
}
});
this.subscription.add(routeSubscription);
}
setSelectedTransaction(transactionId: number): void {
const historyTransaction = this.history.find((transaction) => transaction.id === transactionId);
this.selectedTransaction = historyTransaction;
}
displayTransaction(transaction: Transaction): void {
this.router.navigate(['transactions', transaction.id]);
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
}
这是当前的单元测试:
History.spec.ts
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ActivatedRoute, Resolve, Routes } from '@angular/router';
import { RouterTestingModule } from '@angular/router/testing';
import { Observable, of } from 'rxjs';
import { Transaction } from '../models/transaction.model';
import { HistoryComponent } from './history.component';
import { HistoryResolver } from './history.resolver';
const mockRawTransactions = [
{
"id":"1",
"created_at":"2016-01-01T08:30:39-0300",
"counterparty_name":"Uber",
"debit":"false",
"credit":"true",
"amount":"44.20",
"currency":"EUR",
"operation_type":"refund",
"attachements":[
{
"url":"https:\/\/fakeimg.pl\/350x200\/?text=Hello"
}
],
}
];
const mockTransactions = mockRawTransactions.map((transaction) => new Transaction(transaction));
class HistoryMockResolver implements Resolve<Transaction[]> {
resolve(): Observable<Transaction[]> {
return of(mockTransactions);
}
}
describe('HistoryComponent', () => {
const historyRoutes: Routes = [
{ path: 'transactions', component: HistoryComponent },
{ path: 'transactions/:id', component: HistoryComponent },
];
let component: HistoryComponent;
let fixture: ComponentFixture<HistoryComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ HistoryComponent ],
imports: [
RouterTestingModule.withRoutes(historyRoutes),
],
providers: [
{
provide: ActivatedRoute,
useValue: {
snapshot: {
params: { id: 1 },
},
},
},
{ provide: HistoryResolver, useClass: HistoryMockResolver },
]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(HistoryComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
console.log('Component', component);
expect(component).toBeTruthy();
});
it('should display transactions', () => {
component.history = mockTransactions;
expect(component.history).toBeDefined();
expect(component.history).toHaveSize(mockRawTransactions.length);
});
it('should display a single transaction', () => {
component.history = mockTransactions;
component.displayTransaction(component.history[0]);
expect(component.selectedTransaction).toBeDefined();
expect(component.selectedTransaction).toEqual(component.history[0]);
});
});
在 Karma 中运行测试时,组件已定义并很好地显示在 console.log 中,但 Karma 会为每个测试用例引发错误并将组件评估为未定义。
这是第一个错误:
TypeError: Cannot read property 'history' of undefined
at HistoryComponent.ngOnInit (http://localhost:9876/_karma_webpack_/webpack:/src/app/history/history.component.ts:22:45)
at callHook (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:2486:1)
at callHooks (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:2457:1)
at executeInitAndCheckHooks (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:2408:1)
at refreshView (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:9207:1)
at renderComponentOrTemplate (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:9306:1)
at tickRootContext (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:10532:1)
at detectChangesInRootView (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:10557:1)
at RootViewRef.detectChanges (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/__ivy_ngcc__/fesm2015/core.js:22569:1)
at ComponentFixture._tick (http://localhost:9876/_karma_webpack_/webpack:/node_modules/@angular/core/__ivy_ngcc__/fesm2015/testing.js:141:1)
我应该在我的测试模块中修复什么?
【问题讨论】:
-
你能分享一下 karma 打印的错误信息吗?
-
@deepakchethan 我添加了 Karma 触发的第一个错误,以下是基于相同的问题
-
这里有错误的字段
snapshot: {params: { id: 1 }, },。应该是snapshot: {data: { id: 1 }, },。根据通过this.route.snapshot.data.history引用它
标签: javascript angular karma-runner