1

I am using Unleash SDK client in Angular webapp to have feature toggle functionality in the application.

I have added a service and used UnleashClient from 'unleash-proxy-client'; While writing unit tests for the service added by me, I have to mock the UnleashClient,and did that. But the events such as 'on' are not getting resolved. Does anyone have an idea how to handle this?

Error:

this.unleash.on is not a function

Code:

import {InMemoryStorageProvider, UnleashClient} from 'unleash-proxy-client';
   import {Injectable, OnInit} from '@angular/core';
   import fetchDefaults from 'fetch-defaults';

   @Injectable({
     providedIn: 'root'
   })
   export class UnleashService {
      public static readonly CLIENT_KEY = <client-auth-key>
      public fetchCustomHeaders: any;
      public unleash: UnleashClient;
      private unleashReady: boolean;

      constructor() {
      }

  public initiateUnleashClient() {
    this.fetchCustomHeaders = fetchDefaults(fetch, {
      headers: <added custom headers>
    });
    this.unleash = new UnleashClient({
      url: urlEnums.unleashProxy,
      clientKey: UnleashService.CLIENT_KEY,
      appName: 'my-webapp',
      fetch: this.fetchCustomHeaders,
      environment: 'development',
      storageProvider: new InMemoryStorageProvider()
    });
    this.unleash.on('ready', () => {
      this.unleashReady = true;
    });

  }

  public async isFeatureToggleEnabled(ftName: string): Promise<any> {
    this.initiateUnleashClient();
    await this.unleash.start();
    let isEnabled;
      if (this.unleashReady && this.unleash.isEnabled(ftName)) {
        isEnabled = this.unleash.isEnabled(ftName);
      } else {
        isEnabled = false;
      }
    return Promise.resolve(isEnabled);
  }
}
   

Spec:

import * as UnleashClientModule from 'unleash-proxy-client';
 beforeEach(waitForAsync( () => {
    TestBed.configureTestingModule({
      imports: [
        TranslateModule.forRoot({
          loader: {
            provide: TranslateLoader,
            useClass: WebpackTranslateLoader
          }
        }),
        HttpClientTestingModule
      ],
      providers: [
        ApiHelperService,
        TranslateService,
        HttpTestingController,
      ]
    });
    apiService = TestBed.inject(ApiService);
    unleashService = TestBed.inject(UnleashService);
    UnleashClientSpy = spyOn(UnleashClientModule, 'UnleashClient')
  }));
  it('should generate the custom headers correctly and initialise the unleash client', () => {
    unleashService.initiateUnleashClient();
    // expect(events.includes('ready'));
    expect(UnleashClientSpy.on).toHaveBeenCalledWith();
  });
Prajakta A
  • 68
  • 6

1 Answers1

2

Unfortunately, as Angular and TypeScript progressed, we can't spyOn imports anymore like this:

import * as UnleashClientModule from 'unleash-proxy-client';

UnleashClientSpy = spyOn(UnleashClientModule, 'UnleashClient')

Check this answer for more details.

I also see you didn't include UnleashService in your providers array and I think you should. You should also remove HttpTestingController from providers because HttpClientTestingModule will give you access to it.

To fix this issue, I would move the new UnleashClient to a separate function.

Something like this:

public initiateUnleashClient() {
    this.fetchCustomHeaders = fetchDefaults(fetch, {
      headers: <added custom headers>
    });
    this.unleash = this.createUnleashClient();
    this.unleash.on('ready', () => {
      this.unleashReady = true;
    });

  }

 public createUnleashClient() {
   return new UnleashClient({
      url: urlEnums.unleashProxy,
      clientKey: UnleashService.CLIENT_KEY,
      appName: 'my-webapp',
      fetch: this.fetchCustomHeaders,
      environment: 'development',
      storageProvider: new InMemoryStorageProvider()
    });
 }

And then, in your unit test do the spy on createUnleashClient.

it('should generate the custom headers correctly and initialise the unleash client', () => {
    const onSpy = jasmine.createSpy('onSpy');
    spyOn(service, 'createUnleashClient').and.returnValue({ on: onSpy });
    unleashService.initiateUnleashClient();
    // expect(events.includes('ready'));
    expect(onSpy).toHaveBeenCalled();
  });
AliF50
  • 16,947
  • 1
  • 21
  • 37