1

Here is my component for implementing the swUpdate :

public thereIsUpdate: boolean;

constructor(public swUpdate: SwUpdate) {
    this.checkForUpdates();
}

checkForUpdates() {
  this.swUpdate.checkForUpdate().then(() => {
    this.swUpdate.available.subscribe(swEvt => {
      // an update is available
      this.thereIsUpdate = true;
    });
  });
}

and here is my unit testing :

class MockSwUpdate {
  available = new Subject<{ available: { hash: string } }>().asObservable();
  activated = new Subject<{ current: { hash: string } }>().asObservable();

  public checkForUpdate(): Promise<void> {
    console.log('This is not working');
    return new Promise((resolve) => resolve());
  }
  public activateUpdate(): Promise<void> {
    return new Promise((resolve) => resolve());
  }

  constructor(public isEnabled: boolean) {
  }
}

class MockApplicationRef {
  isStable = new Subject<boolean>();
}

describe('xComponent', () => {
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [
        xComponent
      ],
      imports: [
        RouterTestingModule,
        ServiceWorkerModule.register('', {enabled: false})
      ],
      providers: [
        {provide: SwUpdate, useValue: MockSwUpdate},
        {provide: ApplicationRef, useClass: MockApplicationRef}
      ]
    }).compileComponents();
  }));
}

My problem is cannot doing the "mock" for swUpdate, somehow it is not working.

Somehow the SwUpdate is not mocked even i have specify it.

When i run ng test, it is showing this error :

Uncaught TypeError: this.swUpdate.checkForUpdate is not a function thrown
    TypeError: this.swUpdate.checkForUpdate is not a function

Please note that : The mock is only not working for the SwUpdate.

Sherly Febrianti
  • 1,097
  • 15
  • 33

1 Answers1

-1

For testing a similar service I've manually created an instance per test instead of using the TestBed and passed in a mock swUpdate service as any.

  let mockSwUpdate: any;

  beforeEach(() => {
    mockSwUpdate = {
      isEnabled: false,
      activated: EMPTY,
      available: EMPTY,
      checkForUpdate: () => of(null).toPromise<void>(),
      activateUpdate: () => of(null).toPromise<void>()
    };
  });

  beforeEach(() => {
    mockSwUpdate.isEnabled = true;
  });

  it('should call checkForUpdates', () => {
    spyOn(mockSwUpdate, 'checkForUpdate').and.returnValue(null);

    const service: ServiceWorkerService = new ServiceWorkerService(
      mockSwUpdate as any
    );

    expect(mockSwUpdate.checkForUpdate).toHaveBeenCalled();
  });

  it('should return true is updateAvailbleEmits', (done: DoneFn) => {
    mockSwUpdate.available = of(true);

    const service: ServiceWorkerService = new ServiceWorkerService(
      mockSwUpdate as any
    );

    service.updateAvailable$.subscribe(result => {
      expect(result).toBeTruthy();
      done();
    });
  });
  ...
JayChase
  • 11,174
  • 2
  • 43
  • 52
  • Hi @ JayChase my question is more "SwMock is not working". somehow the unit test is not using the "mock" i created. I want to test my component that used the service worker, not testing the ServiceWorker itself. Could you help? – Sherly Febrianti Nov 11 '19 at 07:20