Unit testing with Angular 12 - Unable to function call inside ngFor loop

Before we fix it, I will try to explain to you what is going wrong so you get a better understanding.

The first call of fixture.detectChanges() is when ngOnInit is called (very important to remember this).

// we change the definition of games$
component.games$ = from([GAME_DATA]) as unknown as Observable<
            IGameData[]
          >;
// we subscribe and see the data
component.games$.subscribe((data: any) => {
     // ---- logged an observable, a proper list of games is returned ----
      console.log('data: ', data);
    });
// we call fixture.detectChanges(); and this calls ngOnInit
fixture.detectChanges();

The problem is that ngOnInit re-assigns this.games$ to a service call therefore losing the definition previously assigned. That's why you see the issue. I hope that makes sense.

To fix it:

I like using createSpyObj for faking the dependencies of external services, follow the lines with !! in the comments.

describe('ListGamesComponent', () => {
  let component: ListGamesComponent;
  let fixture: ComponentFixture<ListGamesComponent>;
  // !! create a mock game service
  let mockGameService: jasmine.SpyObj<GameService>;

  beforeEach(
    waitForAsync(() => {
      // !! assign mockGameService to a spy object with public method of
      // getAllGames
      mockGameService = jasmine.createSpyObj<GameService>('GameService', ['getAllGames']);
      TestBed.configureTestingModule({
        imports: [HttpClientTestingModule, CommonModule],
        declarations: [ListGamesComponent],
        providers: [
          RequestService,
         // !! provide fake GameService for the real GameService
         { provide: GameService, useValue: mockGameService },
        ],
      })
        .compileComponents()
        .then(() => {
          fixture = TestBed.createComponent(ListGamesComponent);
          component = fixture.componentInstance as any;          
        });
    })
  );

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should check if deleteGame was called', fakeAsync(() => {
    spyOn(component, 'deleteGame');
    
    // !! make the mock return a value before ngOnInit is called
    mockGameService.getAllGames.and.returnValue(from([GAME_DATA]) as unknown as Observable<
            IGameData[]
          >);
   
    fixture.detectChanges();

    let button = fixture.debugElement.query(By.css('.delete-game'));
    
    button.triggerEventHandler('click', null);
    fixture.detectChanges();
    tick();

    expect(component.deleteGame).toHaveBeenCalled();
  }));
});

Check this link out on how to mock external dependencies.