angular - 如何测试 BehaviorSubject 的下一个函数?

标签 angular jasmine rxjs behaviorsubject

我正在尝试测试使用 BehaviourSubject 的服务,但我不确定如何进行。这是我的服务:

export class ProductService {
  private changes$: BehaviorSubject<User[]> = new BehaviorSubject([]);

  get products() { return this.changes$.asObservable() as Observable<any>; }

  getProducts() {
    this.http.get(...)
      .subscribe((products) => {
        this.changes$.next(products);
    }
  }

  filterById(id: number) {
    let products = this.products$.getValue().filter(...);
    // Maybe I will have some more filter logic here. 
    // I want to test that the filter logic is returning the correct product
    this.changes$.next(products);
  }
...
}

这是我的测试。我希望能够测试我的服务的过滤逻辑。但是由于我正在模拟数据,this.product$.getValue() 将是空的并且过滤器将不会运行。

it('should filter the products and return the correct product)',
    inject([ProductService], (service: ProductService) => {
      const usersSpy = spyOnProperty(service, 'products', 'get').and.returnValue(Observable.of(mockGetResponse));
      service.products.subscribe((res) => {
        // How do I continue here?  
        // the `this.products$.getValue()` 
        // will not contain any items, 
        // because I am mocking the data. 
        service.findByUserId(1); 
      });
    }));

最佳答案

当您测试一个可观察的序列时,请务必记住发出的值稍后出现(异步)(JavaScript 是单线程的,但您可以将其视为一个单独的线程)。因此,尝试使用模拟数据测试它们并没有明显的错误。

BehaviorSubject 有点极端,因为它被编程为在调用 subscribe() 时发出某种类型的默认值。因此,您可能希望第一次跳过此值。

  it('should emit filtered products', async(inject([ProductService], (service: MockProductService) => {
    let testId = 'testId';  // you need to define this as appropriate
    let testProduct;        // you need to define this to be something that will be returned when the filter is set

    // subscribe, but skip the first as this is a BehaviorSubject and emits a default first value.
    service.filteredProducts$.skip(1).subscribe((o) => expect(o).toBe(testProduct));

    service.findByUserId(testId);
  })));

在这种情况下编写 spy 似乎没有多大意义,因为您所做的只是测试测试代码。如果您正在尝试测试服务本身,您可以 stub 返回服务器的方法,或者您可以编写一个模拟组件(这是我通常做的)来执行此操作(我通常制作我的模拟组件和真正的组件共享一个公共(public)基类)。

关于angular - 如何测试 BehaviorSubject 的下一个函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45494782/

相关文章:

angular - <router-outlet> 在 Angular 9 中不起作用

reactjs - React Enzyme 找到第二个(或第 n 个)节点

angular - 如果术语不为空/空,如何只执行一个 Observable?

javascript - RxJS forkJoin 会按顺序返回结果吗?

javascript - 更新服务中的新值

Angular 2 在路由器导出中设置默认内容

javascript - Angular:如何根据过滤器设置隐藏和显示产品

javascript - javascript上下文中TDD和BDD的区别

rest - 代理后面的请求 promise html 请求

angular - 如何为动态 Angular 组件做依赖注入(inject)