【问题标题】:Mock class in Angular using Jest使用 Jest 在 Angular 中模拟类
【发布时间】:2021-12-21 02:29:35
【问题描述】:

长期以来,我一直在努力模拟我想测试的一个函数。我一直在阅读 Jest 文档,并且我确信答案可能就在某个地方,但我无法将这些部分拼凑在一起以使其发挥作用。我也找不到任何以前的问题让我解决了我的问题,因为我研究的许多问题似乎有点过时了。

这是我要测试的功能(有点简化):

export function getOrganizationAdministrationLinks(permissions: RolePermission[], features: FeatureEnum[],
    translateService: CustomTranslateService): Array<{ name: string, target: string } | 'divider'> {
const uiLinks = new Array<{ name: string, target: string }>();
const organizationLinks = new Array<{ name: string, target: string }>();
const tradingLinks = new Array<{ name: string, target: string }>();

if (havePermissionsAndFeatures(permissions, features, OrganizationSettingsPermissions.permissions, OrganizationSettingsPermissions.features)) {
    uiLinks.push({ name: translateService.get('something'), target: 'interface' });
}

return [uiLinks, organizationLinks, tradingLinks]
    .filter(group => group.length > 0)
    .flatMap(group => [...group, 'divider' as const])
    .slice(0, -1);

我遇到的依赖是CustomTranslateService 之一。它看起来像这样:

export class CustomTranslateService {

public onLangChange: EventEmitter<LangChangeEvent>;

constructor(private readonly translate: TranslateService,
            private readonly userBrowserStateService: UserBrowserStateService) {
    this.onLangChange = this.translate.onLangChange;
    this.setCulture(this.userBrowserStateService.getCulture());
}
/**
 * Returns a translation for the translation key & params.
 */
public get(key: I18nKey): string {
    if (typeof key === 'string') {
        return this.translate.instant(key);
    } else {
        return this.translate.instant(key.key, key.params);
    }
}

我正在苦苦挣扎的部分是,当调用我要测试的函数 getOrganizationAdministrationLinks 时,我必须通过 CustomTranslateServiceCustomTranslateService 本身有依赖关系,我不知道如何模拟它。我怀疑我可能不得不手动模拟它,但感觉有点矫枉过正,因为我只想模拟 get 方法的返回调用。

我只使用jestjest-preset-angular 包。我已经看到了一些使用 ts-jest 的建议,但我不确定是否需要。我也在使用 Angular 12.0.2 和 TypeScript 4.1.3。

【问题讨论】:

  • CustomTranslateService 本身有依赖关系,我不知道如何模拟它” - 为合作者使用测试替身的重点是你不要不必关心它的依赖项是什么,您可以将实际测试的内容与它隔离开来。为什么不只是例如useValue: { get: () =&gt; 'something translated' } 作为测试替身?
  • @jonrsharpe 但我仍然需要在我的测试中将 CustomTranslateService 传递给 getOrganizationAdministrationLinks 函数,这需要 CustomTranslateService 的实例?
  • 不,它不需要,它只是需要一些可以扮演这个角色的东西。 Angular 有自己的 DI 系统可以帮助您解决这个问题,或者在这种情况下您只需将其作为参数传递。
  • @jonrsharpe 关于将它作为参数传递的部分是斗争在哪里。我如何获得可以通过的对象?我看到的所有示例都只是模拟一个类而没有获得可用于传递给方法的实例?谢谢。
  • getOrganizationAdministrationLinks([], [], { get: () =&gt; 'something translated' } as CustomTranslateService)?

标签: angular typescript jestjs


【解决方案1】:

这是一个基本测试,包含我想要达到的解决方案:

    test('getOrganizationAdministrationLinks should return correct name and target when called with rolePermissions and features', () => {
    const expected = [{
        name: 'overruns',
        target: 'interface'
    }];

    const translateService: Partial<CustomTranslateService> = { get: () => 'overruns' } ;
    const actual = getOrganizationAdministrationLinks(rolePermissions, features, translateService as CustomTranslateService);

    expect(actual).toEqual(expected);
});

感谢@jonrsharpe 的一般帮助和链接!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-05-04
    • 2019-09-14
    • 2023-02-21
    • 2021-08-18
    • 2020-11-01
    • 2017-09-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多