0

I have the following services:

@Injectable({
  providedIn: 'root'
})
export class Service1 {
  dataHasChanged = new Subject();
  private data1;
  private data2;

  constructor() {}
  
  getData() {
    return {
      data1: this.data1,
      data2: this.data2
    }
  }

  setData(data1, data2) {
    this.data1 = data1;
    this.data2 = data2;
    this.dataHasChanged.next({
      data1: this.data1,
      data2: this.data2;
    })
  }
}
@Injectable({
  providedIn: 'root'
})
export class Service2 {
  constructor(private service1: Service1) {}

  fetchClient(): Observable<ITest> {
    const data = service1.getData();
    return this.http.post(
      '/api-endpoint/123',
       {
         data: data
        }
     );
  }

  reload(): Observable<ITest> {
    return this.service1.dataHasChanged.pipe(
      mergeMap(() => this.fetchClient()),
    );
  }
}


I want to test that every time dataHasChanged is triggered, a component which has service2.reload(), receives data from its subscription.

I've create the following test for it:

describe('Service2', () => {
  let service2: Service2;
  let httpMock: HttpTestingController;
  let service1: Service1;
  let service1Stub: Partial<Service1>;

  beforeEach(() => {
    service1Stub = {
      dataHasChanged: new Subject(),
      getData: function () {
        return {
          data1: 123,
          data2: 12345
        }
      }
    };
    
    TestBed.configureTestingModule({
      imports: [HttpClientTestingModule],
      providers: [
        Service2,
        {
          provide: Service1,
          useValue: Service1Stub
        }
      ]
    });

    service2 = TestBed.inject(service2);
    httpMock = TestBed.inject(HttpTestingController);
    service1 = TestBed.inject(service1);
  });

it('test', (done: DoneFn) => {  
    service2.reload().subscribe((data) => {
      console.log('here')
      expect(data).toBeDefined();
      done();
    });

    service1.dataHasChanged.next()
  })
});

The problem is that the test which is in subscribe's callback never executes... What's the proper way to write that test?

asotos
  • 327
  • 3
  • 14
  • I've discovered that the problem is `service1.dataHasChanged.next()` which gets the following error `Async function did not complete within 5000m`. But still can't solve that. I've tried to wrap it in waitForAsync/fakeAsync, I solve this problem, but the subscribed code never runs :( – asotos Feb 11 '22 at 20:10

1 Answers1

0

I found out that I was forgetting to mock fetchClient method which has http methods.

This worked:

it('test', (done: DoneFn) => {  
    spyOn(service2, 'fetchData').and.returnValue(of{
        data1: 123,
        data2: 123
    })

    service2.reload().subscribe((data) => {
      console.log('here')
      expect(data).toBeDefined();
      done();
    });

    service1.dataHasChanged.next()
  })
asotos
  • 327
  • 3
  • 14