茉莉花/ Angular:在Init上测试无效EventEmitter的接收情况?

在开始之前,我必须说我对在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的服务。

我当然可以重写服务,只要它能保留其功能即可,但是-是否有一种有效的方法来测试像我这样的“服务”,还是应该以某种方式重写服务?

lisuge 回答:茉莉花/ Angular:在Init上测试无效EventEmitter的接收情况?

问题在于,您正在订阅模拟服务中未定义的toggleSidebar属性。我不确定Jasmine是否支持模拟属性,所以我只会创建一个类似于以下内容的模拟对象。当您想触发事件进行测试时,请执行sideBarSubject.next()。

我也不认为建议在服务中使用EventEmitters。我会更改您的服务以也使用主题。

如果以后需要监视新的模拟侧边栏服务,则可以执行spyOn(sidebarServiceSpy,'showSideBar'),这是必需的,因为您不再将其创建为间谍。

describe('FilterSidebarComponent',() => {
  let component: FilterSideBarComponent;
  let fixture: ComponentFixture<FilterSideBarComponent>;


  let sideBarSubject = new Subject<void>();
  const sidebarServiceSpy = {
    toggleSidebar = sideBarSubject;
    showSidebar: Function(){}
  }

  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();
  });
});
本文链接:https://www.f2er.com/3139672.html

大家都在问