Angular jasmine 测试无法触发使用 fromEvent rxjs 运算符创建的 Observable

Angular jasmine test not able to trigger Observable created with fromEvent rxjs operator

我有一个简单的案例。 Angular 应用程序的标准 AppComponent 包含在其自己的模块 ChildModule.

中定义的 ChildComponent

ChildComponent的模板很简单

<div class="child" (click)="testClick($event)"></div>

ChildComponent 有一个更简单的 testClick(event) 方法,它只在控制台上记录一条消息。

testClick(event) {
    console.log(event);
}

现在我想在 AppComponent 上构建一个模拟点击 ChildComponent 的测试。

这是测试代码

describe('AppComponent', () => {
  let fixture: ComponentFixture<AppComponent>;
  let app: AppComponent;
  let child: DebugElement;

  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [ ChildModule ],
      declarations: [
        AppComponent
      ],
    }).compileComponents();
  }));
  beforeEach(() => {
    fixture = TestBed.createComponent(AppComponent);
    app = fixture.debugElement.componentInstance;
    child = fixture.debugElement.query(By.css('.child'));
    fixture.detectChanges();
  });

  it(`should create the child'`, async(() => {
    expect(child).toBeTruthy();
  }));

  it(`clicks on the child and the relative Observable emits`, async(() => {
    setTimeout(() => {
      child.triggerEventHandler('click', 'clicked');
    }, 100);

  }));

});

测试有效,特别是第二个测试按预期在控制台上打印 clicked 消息。

现在我稍微复杂一点ChildComponent。我想使用 fromEvent 运算符和 ViewChild.

click 事件上创建一个 Observable

所以代码变成

export class ChildComponent implements AfterViewInit {
  @ViewChild('child') private childElement: ElementRef;

  ngAfterViewInit() {
    const testClick$ = fromEvent(this.childElement.nativeElement, 'click');
    testClick$.subscribe(d => console.log('test click in child', d));
  }
}

我用 ng serve 启动了开发服务器,我看到控制台上打印了 2 条消息,一条是 testClick 方法,一条是 testClick$ Observable 的订阅。

如果我现在 运行 进行与以前相同的测试,我希望在控制台上也看到相同的两条消息。相反,我只看到 testClick 方法打印的消息。订阅的消息,即 'test click in child' 没有出现,这意味着 Observable testClick$ 在执行 child.triggerEventHandler('click', 'clicked'); 时不会发出。

如何让 fromEvent 创建的 Observables 在 jasmine 测试中工作?我做错了什么?

最终我找到了一种触发事件的方法,可以在 RxJs 的 fromEvent 函数中使用。

该解决方案的灵感来自 this post

想法是,为了能够从 DOM 事件创建事件流,您必须在 DebugElement 包装的本机元素上使用方法 dispatchEvent

所以,而不是做

child.triggerEventHandler('click', 'clicked');

你必须使用像

这样的东西
child.nativeElement.dispatchEvent(new MouseEvent('click', {...});