【发布时间】:2019-11-08 07:14:46
【问题描述】:
我正在为我的一个组件编写单元测试。所述组件具有visible 布尔值,初始化为假。当该布尔属性变为 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 属性。子组件有自己的手动方法将可见属性重置为 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:无法读取未定义的属性“订阅” 在 在 FilterSideBarComponent.subscribe [as ngOnInit]
我已经在 StackOverflow 中搜索了关于模拟服务订阅方式的类似主题,但我发现的所有示例都使用返回对象、数据或 Observables 的服务。
当然我可以重写服务,只要它保留它的功能,但是 - 有没有一种有效的方法来测试像我这样的“服务”,或者我应该以某种方式重写服务?
【问题讨论】: