【问题标题】:How to mock an angular subscription in Jasmine/Karma如何在 Jasmine/Karma 中模拟 Angular 订阅
【发布时间】:2020-12-21 01:41:47
【问题描述】:

我很难弄清楚如何测试正在使用服务的组件。

我的服务:

export class AgentService {
  private dataCollectorsObervable: Observable<Agent[]> = null;
  private meterOperatorsObervable: Observable<Agent[]> = null;
  private suppliersObervable: Observable<Agent[]> = null;

  private dataCollectorIdSource = new Subject<number>();
  private meterOperatorIdSource = new Subject<number>();

  dataCollectorIdAnnounced$ = this.dataCollectorIdSource.asObservable();
  meterOperatorIdAnnounced$ = this.meterOperatorIdSource.asObservable();

  constructor(private apiService: ApiService) {
  }

  announceDataCollectorId(dataCollectorId: number) {
    this.dataCollectorIdSource.next(dataCollectorId);
  }

  announceMeterOperatorId(meterOperatorId: number) {
    this.meterOperatorIdSource.next(meterOperatorId);
  }
....... 

然后在我的父组件构造函数中订阅服务:

agentService.dataCollectorIdAnnounced$.subscribe();
agentService.meterOperatorIdAnnounced$.subscribe();

在我的代码中进一步使用该服务:

if (isValid) {
        this.getMpanAgentsSubscription = this.agentService.getMpanAgents(this.request.mpan).subscribe((mpanAgents) => {

          if (mpanAgents !== null) {
            this.agentService.announceDataCollectorId(mpanAgents.dataCollectorId);
            this.agentService.announceMeterOperatorId(mpanAgents.meterOperatorId);
            this.getMpanAgentsSubscription = null;
          }
        });
      } else {
        this.agentService.announceDataCollectorId(null);
        this.agentService.announceMeterOperatorId(null);
      }

我的子组件也订阅了该服务,并在初始化时填充了一些下拉列表:

 public dataCollectors: SelectItem[] = [];
  public meterOperators: SelectItem[] = [];
  public dataCollectorSubscription: Subscription;
  public meterOperatorSubscription: Subscription;

  public showMe: boolean = true;

  @Input() public request = null;

  constructor(protected route: ActivatedRoute, private agentService: AgentService) {
    this.dataCollectorSubscription = agentService.dataCollectorIdAnnounced$.subscribe(dataCollectorId => {
      this.request.dataCollectorId = dataCollectorId;
    });

    this.meterOperatorSubscription = agentService.meterOperatorIdAnnounced$.subscribe(meterOperatorId => {
      this.request.meterOperatorId = meterOperatorId;
    });

  }

  ngOnInit(): void {
    const agents: AgentLists = this.route.snapshot.data['agents'];

    this.dataCollectors.push({ label: '', value: null });
    for (const agent of agents.dataCollectors) {
      this.dataCollectors.push({ label: agent.name, value: agent.id });
    }

    this.meterOperators.push({ label: '', value: null });
    for (const agent of agents.meterOperators) {
      this.meterOperators.push({ label: agent.name, value: agent.id });
    }
  }

原来子组件中的所有代码都在父组件中。我已将这部分组件化,因为我们在多个地方使用它。代码运行良好,但从父级移出代码破坏了我们所有的测试。

我的 agentservice.getMpanAgents 规范文件中的存根是:

agentServiceStub = {
        getMpanAgents(mpan: string): Observable<MpanAgents> {
          if (mpan === mpanValidWithDetails) {
            return new BehaviorSubject<MpanAgents>(new MpanAgents());
          } else {
            return new BehaviorSubject<MpanAgents>(null);
          }
        }

我正在努力改变它以适应我的代码的新结构。

【问题讨论】:

    标签: angular jasmine


    【解决方案1】:

    我觉得你可以考虑使用ng-mocks

    它有MockInstancengMocks.defaultMock

    依赖关系可能会被伪造的 observables 模拟:

    const fakeStream$ = new Subject();
    const fakeData$ = new Subject(); // Or EMPTY if you don't need it in test.
    const fakeMeter$ = new Subject();
    
    beforeAll(() => MockInstance(AgentService, () => ({
      getMpanAgents: () => fakeStream$,
      dataCollectorIdAnnounced$: fakeData$,
      meterOperatorIdAnnounced$: fakeMeter$,
    })));
    
    afterAll(MockReset);
    
    beforeEach(() => MockBuilder(ComponentToTest)
      .mock(ChildComponent)
      .mock(AgentService));
    
    it('test', () => {
      const fixture = MockRender(ComponentToTest);
      fakeStream$.next('someVlue');
      fakeMeter$.next('anotherValue');
      // ....
    });
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-01-12
      • 1970-01-01
      • 1970-01-01
      • 2014-12-12
      • 2013-12-20
      • 1970-01-01
      • 2017-09-04
      相关资源
      最近更新 更多