在单元测试中模拟 Unleash 客户端 SDK 时出现问题

发布于 2025-01-11 09:42:13 字数 2557 浏览 0 评论 0原文

我在 Angular web 应用程序中使用 Unleash SDK 客户端,以便在应用程序中具有功能切换功能。

我添加了一项服务并使用了“unleash-proxy-client”中的 UnleashClient; 在为我添加的服务编写单元测试时,我必须模拟 UnleashClient,并做到了这一点。但诸如“on”之类的事件并未得到解决。有谁知道如何处理这个问题?

错误:

this.unleash.on 不是函数

代码:

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);
  }
}
   

规格:

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();
  });

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();
  });

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

风吹短裙飘 2025-01-18 09:42:13

不幸的是,随着 Angular 和 TypeScript 的进步,我们不能再像这样 spyOn 导入:

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

UnleashClientSpy = spyOn(UnleashClientModule, 'UnleashClient')

检查 这个答案了解更多详细信息。

我还发现您没有在 providers 数组中包含 UnleashService ,我认为您应该这样做。您还应该从 providers 中删除 HttpTestingController,因为 HttpClientTestingModule 将使您能够访问它。

为了解决这个问题,我将新的 UnleashClient 移动到一个单独的函数中。

像这样的事情:

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()
    });
 }

然后,在您的单元测试中对 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();
  });

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();
  });
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文