Bla*_*axy 36 typescript karma-runner karma-jasmine angular
我正在测试订阅路由器参数的组件.每个测试通过,一切正常.但如果我查看控制台,我会看到一个错误:
清理组件ApplicationViewComponent localConsole时出错.(匿名函数)@ context.js:232
你知道为什么会这样吗?
我尝试删除unsubscribe()from ngOnDestroy()方法,错误消失.
karma/jasmine会unsubscribe()自动支持吗?
这是组件和测试
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs/Rx'
import { AppService } from 'app.service';
@Component({
selector: 'app-component',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
private routeSubscription: Subscription;
// Main ID
public applicationId: string;
constructor(
private route: ActivatedRoute,
private _service: AppService
) { }
ngOnInit() {
this.routeSubscription = this.route.params.subscribe(params => {
this.applicationId = params['id'];
this.getDetails();
this.getList();
});
}
getDetails() {
this._service.getDetails(this.applicationId).subscribe(
result => {
console.log(result);
},
error => {
console.error(error);
},
() => {
console.info('complete');
}
);
}
getList(notifyWhenComplete = false) {
this._service.getList(this.applicationId).subscribe(
result => {
console.log(result);
},
error => {
console.error(error);
},
() => {
console.info('complete');
}
);
}
ngOnDestroy() {
this.routeSubscription.unsubscribe();
}
}
Run Code Online (Sandbox Code Playgroud)
import { NO_ERRORS_SCHEMA } from '@angular/core';
import {
async,
fakeAsync,
ComponentFixture,
TestBed,
tick,
inject
} from '@angular/core/testing';
import {
RouterTestingModule
} from '@angular/router/testing';
import {
HttpModule
} from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { Router, ActivatedRoute } from '@angular/router';
// Components
import { AppComponent } from './app.component';
// Service
import { AppService } from 'app.service';
import { AppServiceStub } from './app.service.stub';
let comp: AppComponent;
let fixture: ComponentFixture<AppComponent>;
let service: AppService;
let expectedApplicationId = 'abc123';
describe('AppComponent', () => {
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [AppComponent],
imports: [RouterTestingModule, HttpModule],
providers: [
FormBuilder,
{
provide: ActivatedRoute,
useValue: {
params: Observable.of({id: expectedApplicationId})
}
},
{
provide: AppService,
useClass: AppServiceStub
}
],
schemas: [ NO_ERRORS_SCHEMA ]
})
.compileComponents();
}));
tests();
});
function tests() {
beforeEach(() => {
fixture = TestBed.createComponent(AppComponent);
comp = fixture.componentInstance;
service = TestBed.get(AppService);
});
/*
* COMPONENT BEFORE INIT
*/
it(`should be initialized`, () => {
expect(fixture).toBeDefined();
expect(comp).toBeDefined();
});
/*
* COMPONENT INIT
*/
it(`should retrieve param id from ActivatedRoute`, async(() => {
fixture.detectChanges();
expect(comp.applicationId).toEqual(expectedApplicationId);
}));
it(`should get the details after ngOnInit`, async(() => {
spyOn(comp, 'getDetails');
fixture.detectChanges();
expect(comp.getDetails).toHaveBeenCalled();
}));
it(`should get the list after ngOnInit`, async(() => {
spyOn(comp, 'getList');
fixture.detectChanges();
expect(comp.getList).toHaveBeenCalled();
}));
}
Run Code Online (Sandbox Code Playgroud)
import { Observable } from 'rxjs/Observable';
export class AppServiceStub {
getList(id: string) {
return Observable.from([
{
id: "7a0c6610-f59b-4cd7-b649-1ea3cf72347f",
name: "item 1"
},
{
id: "f0354c29-810e-43d8-8083-0712d1c412a3",
name: "item 2"
},
{
id: "2494f506-009a-4af8-8ca5-f6e6ba1824cb",
name: "item 3"
}
]);
}
getDetails(id: string) {
return Observable.from([
{
id: id,
name: "detailed item 1"
}
]);
}
}
Run Code Online (Sandbox Code Playgroud)
ran*_*son 69
接受的解决方案不是最佳解决方案,它解决了测试设置不正确的问题.
发生"组件清理期间出错"错误消息,因为ngOnDestroy()调用时this.routeSubscription未定义.发生这种情况是因为ngOnInit()从未调用过,这意味着您从未订阅过该路由.如Angular测试教程中所述,在您fixture.detectChanges()第一次调用之前,组件未完全初始化.
因此,正确的解决方案是在调用后立即添加fixture.detectChanges()到beforeEach()块中createComponent.它可以在您创建夹具后随时添加.这样做将确保组件完全初始化,组件清理也将按预期运行.
mus*_*ecz 28
你需要重构你的方法ngOnDestroy,如下所示:
ngOnDestroy() {
if ( this.routeSubscription)
this.routeSubscription.unsubscribe();
}Run Code Online (Sandbox Code Playgroud)
Ale*_*ink 12
就我而言,每次测试后销毁组件就解决了问题。所以你可以尝试将其添加到你的描述函数中:
afterEach(() => {
fixture.destroy();
})
Run Code Online (Sandbox Code Playgroud)
我处于类似的情况,我想在组件本身的上下文之外测试组件中的函数。
这对我有用:
afterEach(() => {
spyOn(component, 'ngOnDestroy').and.callFake(() => { });
fixture.destroy();
});
Run Code Online (Sandbox Code Playgroud)
小智 6
所以我的情况类似,但不完全相同:我只是把它放在这里以防其他人觉得它有用.当我用Jamine/Karma进行单元测试时
'ERROR: 'Error during cleanup of component','
Run Code Online (Sandbox Code Playgroud)
事实证明这是因为我没有正确处理我的observable,并且他们没有错误函数.所以修复是添加一个错误函数:
this.entityService.subscribe((items) => {
///Do work
},
error => {
this.errorEventBus.throw(error);
});
Run Code Online (Sandbox Code Playgroud)
小智 6
你可以加
拆解:{ destroyAfterEach: false },
在 TestBed.configureTestingModule 中,它看起来像这样
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [<Your component here>],
imports: [<Your imports here>],
providers: [<Your providers here>],
teardown: { destroyAfterEach: false },
}).compileComponents();
});Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
22709 次 |
| 最近记录: |