【问题标题】:How to test subscription code after pipe(takeWhile(...)) in Angular 7如何在Angular 7中的管道(takeWhile(...))之后测试订阅代码
【发布时间】:2019-06-21 22:02:26
【问题描述】:

令我惊讶的是,尽管进行了大量搜索,但我仍然无法找到答案......

我正在尝试测试我的订阅代码是否正确。我之前在 Angular 2 中做过无数次,但我们刚刚开始了一个新项目,所以我们使用的是最新的 Angular,它重新编写了 rxjs,将链接更改为管道,现在我不知道是什么模拟或如何做。

给定:

  constructor(private media: MediaObserver) { }

  ngOnInit() {
    this.active = true;

    this.media.media$.pipe(takeWhile((ev) => this.active)).subscribe((change: MediaChange) => {
      if (change.mqAlias === "xs" || change.mqAlias === "sm") {
        this.stackFooter = true;
      } else {
        this.stackFooter = false;
      }
    });
  }

如何编写 karma/jasmine 测试以确保在媒体服务触发事件时正确设置 this.stackFooter? 例如,我试图监视各种事物(media$、“pipe”),但似乎 takeWhile() 返回了一个我似乎无权访问的新 Observable?我该如何测试呢?或者,这不再是推荐的模式,我应该完全做其他事情吗?

【问题讨论】:

    标签: angular rxjs karma-jasmine


    【解决方案1】:

    实际上它正在返回一个新的 Observable,但你并不关心 Observable 本身你关心它包含的流,尝试这样做:

    在你的测试中

    let mockMediaSubject: BehaviorSubject<MediaChange>;
    ...
    beforeEach(() => {
       mockMediaSubject = new BehaviorSubject({});
       TestBed.configureTestModule({
          ...
          providers: [ 
             { 
                 provide: MediaObserver, 
                 useValue: { media$: mockMediaSubject.asObservable() }
             }
          ]
       });
    });
    
    ...
    it("should set stackFooter to true when media$ emits 'xs' as mqAlias", () => {
       mockMediaSubject.next({mqAlias: 'xs'});
    
       expect(componentInstance.stackFooter).toBeTruthy();
    });
    ...
    it("should set stackFooter to true when media$ emits 'sm' as mqAlias", () => {
       mockMediaSubject.next({mqAlias: 'sm'});
    
       expect(componentInstance.stackFooter).toBeTruthy();
    });
    

    哇,很难将它输入到那个编辑器中。如果我错过了某些东西并且它不起作用,请添加我的名字的评论,以便我看到它。希望对您有所帮助。

    【讨论】:

    • 感谢您的回复。测试现在失败:失败:NgModule 'DynamicTestModule' 的提供程序无效 - 只允许提供 Provider 和 Type 的实例,得到:[?[object Object]?, ...] 我还必须在其中添加“as MediaChange”几个地方。
    • 那你还有问题吗?
    • 错误是因为我使用“provider”而不是“provide”来定义 MediaObserver。哇!
    • 我已经接受这是最佳答案,即使我没有逐字使用它。我最终创建了一个单独的模拟对象:media$: Subject&lt;MediaChange&gt; = new Subject&lt;MediaChange&gt;(); 作为成员,然后使用spyOn(this.media$, "subscribe").and.callThrough(); 创建了一个构造函数。我通过providers: [ { provide: MediaObserver, useClass: MediaObserverMock}], 将其提供给测试用例。其余的基本上是答案中指定的内容。谢谢!
    • 您可以将代码发布到您的解决方案中吗?一年过去了,尽管进行了很多搜索,但我没有找到一个非常明显的解决方案。
    猜你喜欢
    • 2021-04-08
    • 2023-02-06
    • 1970-01-01
    • 2023-03-25
    • 2020-06-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多