Angular unit tests - mock service with observable

189 Views Asked by At

I'm trying to fix my unit tests of a component that subscribes to an Observable of the service DataService during ngOnInit(). However, at the moment I'm still getting TypeError: Cannot read properties of undefined (reading 'subscribe').

I tried to create a MockDataService that contains the Observable but it still doesn't work. Even though I'm fairly inexperienced with unit tests, I feel like I've successfully done something similar to this.

startpage.component.ts

...

@Component({
  selector: 'app-startpage',
  templateUrl: './startpage.component.html',
  styleUrls: ['./startpage.component.scss']
})
export class StartpageComponent implements OnInit {

  public data: Data = {};

  constructor(private dataService: DataService) { }

  ngOnInit(): void {
   // error during unit test happens here 
    this.dataService.data$.subscribe((data: Data) => {
      this.data = data;
    });
  }
}

startpage.component.spec.ts

...

describe('StartpageComponent', () => {
  let component: StartpageComponent;
  let fixture: ComponentFixture<StartpageComponent>;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      declarations: [StartpageComponent],
      imports: [],
      providers: [
        { provide: DataService, useValue: MockDataService }
      ]
    })
      .compileComponents();

    fixture = TestBed.createComponent(StartpageComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

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

// MockDataService 
class MockDataService {
  public data$: Observable<Data> = of({});
}

1

There are 1 best solutions below

0
Charleston Campos On

Your mock is probably not working as expected.

First: See if the service you are trying to mock has the possibility of returning data$ null.

Second: Try using overrideComponent at the initialization of your test. It would be something similar to this:

TestBed.overrideComponent(StartpageComponent, {
  set: {
    providers: [
      { provide: DataService, useClass: MockDataService }
    ]
  }
})

This change would be after the compileComponents();