0

我有使用LocaleService该服务的类和静态方法的组件instant()LocaleService在未注入组件中。在测试组件时,我对LocaleService内部不感兴趣,也不想测试它。因此,beforeEach我添加了一个间谍

const localeServiceInstantSpy = spyOn(LocaleService, 'instant');
localeServiceInstantSpy.and.callFake(msg => msg);

这工作得很好。现在我需要将这个间谍(和其他)移动到一个存根,LocaleService并在这个测试和其他组件的测试中使用它LocaleService- 其中有很多。实现这一目标的最正确方法是什么?如何创建可重用的 LocaleServiceStub?

\app\utils\locale.service.ts

export class LocaleService {

    public static lang: string;

    private static messages = {
        'user.add': {
            en: 'Add Local User Account',
            de: 'Add Local User Account DE'
        },
        'user.edit': {
            en: 'Edit Local User Account',
            de: 'Edit Local User Account DE'
        }
    };

    public static instant(key: string) {
        return this.messages[key][this.lang];
    }

}

在被测类中的使用\app\settings\users\user-form.component.ts

import { LocaleService } from 'app/utils/locale.service';
...
getDialogHeader() {
    return this.isNewUser ? LocaleService.instant('user.add') : LocaleService.instant('user.edit');
}
...
4

1 回答 1

1

纯静态类在 JavaScript 中有代码异味。如果一个类从不被实例化,那就没有必要了。

这是 Angular DI 应该解决的情况之一。它应该被重构为一个服务而不是一个直接使用的类。

class LocaleService {
    public lang: string;

    private messages = {...};

    public instant(key: string) {
        return this.messages[key][this.lang];
    }
}

...
providers: [LocaleService, ...]
...

然后就可以通过DI来模拟了。为了被重用,可以将模拟定义为提供者:

const LOCALE_SERVICE_MOCK = {
  provide: LocaleService,
  useFactory: () => ({
    instant: jasmine.createSpy('instant').and.callFake(msg => msg)
  })
};

并在测试台中指定:

beforeEach(() => {
  TestBed.configureTestingModule({ providers: [LOCALE_SERVICE_MOCK]});
});

或者用一个模块包裹:

beforeEach(() => {
  TestBed.configureTestingModule({ imports: [LocaleServiceMockModule]});
});

在当前状态下,可以通过将可重用代码移动到函数来使代码变得 DRYer:

function mockLocaleService() {
  const localeServiceInstantSpy = spyOn(LocaleService, 'instant');
  localeServiceInstantSpy.and.callFake(msg => msg);
}

并在需要的地方使用它:

beforeEach(mockLocaleService);
于 2018-05-25T10:01:47.433 回答