我必须为angular 5应用程序编写单元测试。为此,我使用jasmine + jest
(为了测试速度,我们使用玩笑代替公司中的业力)。
为了测试组件的行为(请参见下面的代码),我创建了一个测试,该测试与被测组件订阅了相同的Observable
,然后在希望组件的订阅代码块有足够的时间来完成,然后查找组件的内部更改。
问题在于,随着测试数量的增加,完成测试所需的时间也会增加。我个人认为,下面必须有一种更好的方法来测试这种类型的代码。
async
,但找不到找到适合自己需求的方法。 预先感谢您的帮助。
import { Component, OnInit, OnDestroy } from '@angular/core';
import { SomeService } from './some.service';
@Component({
selector: 'app-dummy',
templateUrl: './dummy.component.html',
styleUrls: ['./dummy.component.scss']
})
export class DummyComponent implements OnInit, OnDestroy {
isEditable: Boolean;
//...
private aSubscriber;
constructor(private someService: SomeService) {
this.aSubscriber = someService.anObservable$.subscribe(value => {
this.isEditable = value;
});
}
ngOnInit() { }
ngOnDestroy() {
this.aSubscriber.unsubscribe();
}
}
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Subject } from 'rxjs/Subject';
@Injectable()
export class SomeService {
private aSubject = new Subject<any>();
anObservable$ = this.aSubject.asObservable();
constructor() { }
notify(value) {
this.aSubject.next(value);
}
}
import { async, ComponentFixture, TestBed, inject } from '@angular/core/testing';
import { DummyComponent } from './dummy.component';
import { SomeService } from './some.service';
describe('DummyComponent', () => {
let component: DummyComponent;
let fixture: ComponentFixture<DummyComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [DummyComponent],
providers: [SomeService]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(DummyComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
it('should subscribe to anObservable and set values according to the received one',
inject([SomeService], (service: SomeService) => {
service.anObservable$.subscribe(value => {
setTimeout(() => { }, 2000);
//Test that values are correctly set in the component under test.
expect(component.isEditable).toBeTruthy();
//...
});
service.notify(true);
}));
});
答案 0 :(得分:5)
我经常发现我的代码可以进行某种程度的重构以适应测试,并且重构通常会使代码的紧密耦合性降低,更加灵活并且易于阅读。
出于这种考虑,我建议您采用订阅的“下一个”处理程序中当前拥有的代码,并将其提取到单独的方法中。
例如,以
constructor(private someService: SomeService) {
this.aSubscriber = someService.anObservable$.subscribe(value => {
this.isEditable = value;
});
}
并将其重构为:
constructor(private someService: SomeService) {
this.aSubscriber = someService.anObservable$.subscribe(value => {
this.onValue(value);
});
}
private onValue(value) {
this.isEditable = value;
}
然后,您可以直接直接测试“ onValue”方法,而不必测试Observable。我认为,除非您对Observable进行更高级的操作(将其插入map(),filter()等),否则无需测试Observable,并且可以删除测试的异步方面。
如果您有高级管道,则可能应该单独对其进行测试。 像这样拆分它可以分别测试这两种情况。