单元测试中mocking Unleash客户端SDK的问题



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

我添加了一项服务,并使用了来自"释放代理客户端"的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();
});

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

import * as UnleashClientModule from 'unleash-proxy-client';
UnleashClientSpy = spyOn(UnleashClientModule, 'UnleashClient')

查看此答案以了解更多详细信息。

我还看到您没有在providers数组中包含UnleashService,我认为您应该这样做。您还应该从providers中删除HttpTestingController,因为HttpClientTestingModule将允许您访问它

为了解决这个问题,我将把new 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();
});

最新更新