如何在Angular单元测试里,对class protected方法进行测试

发表于:2022-5-16 09:49

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:JerryWang汪子熙    来源:51CTO博客

  例子:
  我的service class里有一个protected方法,我想在单元测试里对其进行测试:
  一种思路是,可以沿用Java里测试protected方法的变通方式,即创建一个新的sub class,继承包含该protected方法的class,然后在子类里新建一个公有方法作为wrapper之用,实现逻辑只有一行,就是调用父类的protected方法。
  例子如下:
  这样,我只需要对子类的公有方法进行单元测试即可测试到父类的protected方法。
  完整源代码:
  import { Injectable } from '@angular/core';
  import { TestBed } from '@angular/core/testing';
  import { EntitiesModel } from '@spartacus/core';
  import {
    B2BUnitNode,
    B2BUnitTreeNode,
    OrgUnitService,
  } from '@spartacus/organization/administration/core';
  import { TableService, TableStructure } from '@spartacus/storefront';
  import { BehaviorSubject, Observable, of } from 'rxjs';
  import { UnitItemService } from './unit-item.service';
  import { UnitListService } from './unit-list.service';
  import { TREE_TOGGLE } from './unit-tree.model';
  import { UnitTreeService } from './unit-tree.service';
  import createSpy = jasmine.createSpy;
  function verifyExpandedAll({ values }: EntitiesModel<B2BUnitTreeNode>) {
    expect(values.length).toEqual(7);
    values.forEach((element) => {
      expect(element.expanded).toBeTrue();
    });
  }
  function verifyCollapsedAll({ values }: EntitiesModel<B2BUnitTreeNode>) {
    const root = values[0];
    expect(values.length).toEqual(1);
    expect(root.uid).toEqual(mockedTree.id);
    expect(root.expanded).toBeFalse();
    expect(root.depthLevel).toEqual(0);
    expect(root.count).toEqual(mockedTree.children.length);
  }
  const codeKey = 'uid';
  const mockedTree = {
    id: 'Rustic',
    name: 'Rustic',
    active: true,
    children: [
      {
        id: 'Rustic Services',
        name: 'Rustic Services',
        parent: 'Rustic',
        active: true,
        children: [
          {
            active: true,
            children: [],
            id: 'Services West',
            name: 'Services West',
            parent: 'Rustic Services',
          },
          {
            active: true,
            children: [],
            id: 'Services East',
            name: 'Services East',
            parent: 'Rustic Services',
          },
        ],
      },
      {
        id: 'Rustic Retail',
        name: 'Rustic Retail',
        parent: 'Rustic',
        active: true,
        children: [
          {
            active: true,
            id: 'Custom Retail',
            name: 'Custom Retail',
            parent: 'Rustic Retail',
            children: [
              {
                active: true,
                children: [],
                id: 'Test',
                name: 'TestUnit',
                parent: 'Custom Retail',
              },
            ],
          },
        ],
      },
    ],
  };
  const mockedTreeBeforeConvert = {
    id: 'Rustic',
    name: 'Rustic',
    active: true,
    children: [
      {
        id: 'test3',
        name: 'test3',
        parent: 'Rustic',
        active: true,
        children: [],
      },
      {
        id: 'test1',
        name: 'test1',
        parent: 'Rustic',
        active: true,
        children: [],
      },
      {
        id: 'test2',
        name: 'test2',
        parent: 'Rustic',
        active: true,
        children: [],
      },
    ],
  };
  const mockedTreeAfterConvert = {
    pagination: {
      totalResults: 4,
    },
    values: [
      {
        active: true,
        children: [
          {
            id: 'test1',
            name: 'test1',
            parent: 'Rustic',
            active: true,
            children: [],
          },
          {
            id: 'test2',
            name: 'test2',
            parent: 'Rustic',
            active: true,
            children: [],
          },
          {
            id: 'test3',
            name: 'test3',
            parent: 'Rustic',
            active: true,
            children: [],
          },
        ],
        count: 3,
        depthLevel: 0,
        expanded: false,
        id: 'Rustic',
        name: 'Rustic',
        uid: 'Rustic',
      },
    ],
  };
  const treeToggle$ = new BehaviorSubject(
    new Map().set(mockedTree.id, TREE_TOGGLE.EXPANDED)
  );
  class MockUnitService {
    getTree(): Observable<B2BUnitNode> {
      return of(mockedTree);
    }
  }
  @Injectable()
  export class MockTableService {
    buildStructure(type): Observable<TableStructure> {
      return of({ type });
    }
  }
  export class MockUnitTreeService {
    treeToggle$ = treeToggle$.asObservable();
    initialize = createSpy('initialize');
    getToggleState = createSpy('getToggleState')
      .withArgs(mockedTree.id)
      .and.returnValue(treeToggle$.value?.get(mockedTree.id));
    isExpanded = createSpy('isExpanded').and.returnValue(false);
  }
  export class UnitListServiceForSortTest extends UnitListService {
    public convertListItemWrapper(unit: B2BUnitNode) {
      return this.convertListItem(unit);
    }
  }
  describe('UnitListService', () => {
    let service: UnitListService;
    let treeService: UnitTreeService;
    describe('with table config', () => {
      beforeEach(() => {
        TestBed.configureTestingModule({
          providers: [
            {
              provide: UnitListService,
              useClass: UnitListServiceForSortTest,
            },
            {
              provide: UnitTreeService,
              useClass: MockUnitTreeService,
            },
            {
              provide: OrgUnitService,
              useClass: MockUnitService,
            },
            {
              provide: TableService,
              useClass: MockTableService,
            },
            {
              provide: UnitItemService,
              useValue: {
                key$: of(mockedTree.id),
              },
            },
          ],
        });
        service = TestBed.inject(UnitListService);
        treeService = TestBed.inject(UnitTreeService);
      });
      it('should inject service', () => {
        expect(service).toBeTruthy();
      });
      it('should return "code" key', () => {
        expect(service.key()).toEqual(codeKey);
      });
      it('should get collapsed all items structure', () => {
        let result: EntitiesModel<B2BUnitTreeNode>;
        service.getData().subscribe((table) => (result = table));
        verifyCollapsedAll(result);
      });
      it('should get expanded all items structure', () => {
        let result: EntitiesModel<B2BUnitTreeNode>;
        treeService.isExpanded = createSpy().and.returnValue(true);
        service.getData().subscribe((table) => (result = table));
        verifyExpandedAll(result);
      });
      it('should automatically sort unit tree by name', () => {
        const serviceForSort = service as UnitListServiceForSortTest;
        const convertedTree = serviceForSort.convertListItemWrapper(
          mockedTreeBeforeConvert
        );
        expect(convertedTree).toEqual(mockedTreeAfterConvert);
      });
    });
  });
 
  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号