在开始之前,我必须说我对在Jasmine中进行测试非常陌生。这是我学习时没有特别注意或努力的事情之一,现在我对此感到遗憾。
无论如何,我正在为我的组件之一编写单元测试。所述组件具有一个visible
布尔值,初始化为false。当上述boolean属性变为true时,组件的display css属性从无变为块,使其可见。
由于我的组件是子组件,因此我建立了一个周期,以使父组件从技术上“触发”该组件:
- 该组件初始化为不可见状态。父母和孩子都连接到服务,如下所示:
export class SidebarService {
public toggleSidebar: EventEmitter<void> = new EventEmitter();
constructor() {}
public showSidebar() {
this.toggleSidebar.emit();
}
}
该服务不需要连接到任何端点,也不需要返回任何数据:发射器充当子组件的“每次单击一次”信号。
- 单击父模板中的一个按钮,父调用以下方法:
toggleSidebar() {
this.sidebarService.showSidebar();
}
- 在子组件的OnInit上,我写了以下内容:
ngOnInit() {
this.sidebarService.toggleSidebar.subscribe(() => {
this.visible = true;
});
}
因此,当父级触发事件发射器时,子级将接收它并更改其visible
属性。子组件具有自己的手动方法,可以将visible属性重置为false。
从功能的角度来看,它可以完成工作:当父组件单击按钮时,组件“出现”。但是现在我担心我可能会破坏他们之间关系的“连接性”。
编写单元测试时,到目前为止,我对组件的了解如下:
describe('FilterSidebarComponent',() => {
let component: FilterSideBarComponent;
let fixture: ComponentFixture<FilterSideBarComponent>;
const sidebarServiceSpy = jasmine.createSpyObj('SidebarService',[
'showSidebar'
]);
const fb: FormBuilder = new FormBuilder();
configureTestSuite(() => {
TestBed.configureTestingModule({
imports: [
MockModule(FormsModule),MockModule(ReactiveFormsModule),MockModule(TranslateModule.forRoot())
],declarations: [
FilterSideBarComponent,CheckboxInputComponent,MockComponent(CountrySingleSearchComponent),MockComponent(UniversitiesSearcherComponent)
],providers: [
{provide: SidebarService,useValue: sidebarServiceSpy},{provide: FormBuilder,useValue: fb},]
});
});
beforeEach(() => {
fixture = TestBed.createComponent(FilterSideBarComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create',() => {
expect(component).toBeTruthy();
});
});
并且到目前为止编写的唯一测试(“应该创建”)失败了,Jasmine告诉我: TypeError:无法读取未定义的属性“ subscribe” 在 在FilterSideBarComponent.subscribe [as ngOnInit]
我在StackOverflow中搜索了类似的主题,以模拟服务订阅的方式,但是我发现的所有示例都使用返回对象,数据或Observable的服务。
我当然可以重写服务,只要它能保留其功能即可,但是-是否有一种有效的方法来测试像我这样的“服务”,还是应该以某种方式重写服务?