简体   繁体   中英

How to unit test Rxjs combineLatest?

My component's ngOnInit does this

public ngOnInit() {
    this.ctrSubscription = combineLatest(this.route.queryParams, this.tags$).subscribe(async params => {
      if (Object.keys(params[0]).length > 0) {
        this.initView({ ...params[0] });
      }
      if (Object.keys(params[1]).length > 0) {
        this.wsTags = Object.values(params[1]);
      }
      if (params[0] && this.wsTags.length > 0) {
        this.searchWs({ ...params[0] }.q);
        this.pruneData();
      }
    });
  }

And this is how i am testing it

  it('should perform search and load the results', fakeAsync(() => {
    TestBed.get(ActivatedRoute).queryParams = of({ q: 'test' });
    const initSpy = spyOn<any>(component, 'initView').and.callThrough();
    const subSpy = spyOn<any>(component.tags$, 'subscribe');
    component.wsTags = ensureState(mockTags as any);
    flushMicroTasks();
    fixture.detectChanges();
    flushMicroTasks();
    expect(initSpy).toHaveBeenCalledWith({ q: 'test' });
    expect(subSpy).toHaveBeenCalled();
    expect(component.wsTags).toBe(Object.values(mockTags));
  }));

the spys are not getting called at all.I put a breakpoint when running tests to know if the value is passing or not , and i was able to catch the query params being passed correctly but still the if fails.

I tried going through the docs to understand better and also various similar questions here on stack overflow, i couldn't able to solve it. I am fairly new to writing unit tests, so any help will be appreciated. Thanks.

One potential issue is that you're mocking ActivatedRoute within the it block. This is too late, your ngOnInit runs after the first detectChanges after compileComponents .

When configuring your testing module, try:

describe('Put description of the test', () => {
  let component: YourComponent;
  let activatedRoute: ActivatedRoute;
  let fixture: ComponentFixture<YourComponent>;

  beforeEach(() => {
    TestBed.configureTestingModule({
     declarations: [ YourComponentToTest, 
      // other declarations if need be.
     ],
     providers: [
      provide: ActivatedRoute,
      useValue: {
       queryParams: of({ q: 'test" }),
      }
     ]
   }).compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(YourComponentToTest);
    component = fixture.componentInstance;
    activatedRoute = TestBed.get(ActivatedRoute);
    // ngOnInit is ran now -- after the first detectChanges
    fixture.detectChanges();
  });

  it('should do what you want', () => {
   // your arrange, act, and assertions.
  });
})

Make sure this.tags$ is initialized as well.

I did all of this freehand so there may be typo(s).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM