unit-testing - 测试具有服务依赖性的服务

标签 unit-testing angular typescript testing

我无法找到将其他服务作为依赖项来测试服务的正确解决方案。我正在测试的服务调用另一个返回任务列表的服务的 getter 方法。这是我正在测试的服务:

服务测试:

export class TasksData {
  public tasks = [];
  public tasksData = [
    {
      'form': 'setup-device',
      'type': 'register-device',
      'text': 'Register Device',
      'icon': 'mdi-cellphone-link',
      'status': ''
    },
    {
      'form': 'setup-eula',
      'type': 'confirm-eula',
      'text': 'Agree to EULA',
      'icon': 'mdi-pen',
      'status': ''
    },
    {
      'form': 'setup-change-password',
      'type': 'change-password',
      'text': 'Change Password',
      'icon': 'mdi-lock-reset',
      'status': ''
    },
    {
      'form': 'setup-profile',
      'type': 'register-profile',
      'text': 'Register Profile',
      'icon': 'mdi-account-plus',
      'status': ''
    }
  ];

  constructor(private setupManager: SetupManagerService) {}

  public getter() {
    let data = [];
    this.tasks = this.setupManager.getter();

    data = this.tasksData.filter((task) => {
      return (this.tasks.indexOf(task.type)) !== -1;
    });

    return data;
  }
}

依赖服务:

export class SetupManagerService {
  private message: string;
  private redirect = '';
  private tasks: any = [];
  private clone: any = [];
  private user: Object = {};

  public taskChange = new Subject();

  constructor(
    private closeModal: CloseModalService,
    private pubsub: Pubsub,
    private reloadStatus: ReloadStatusService,
    private router: Router,
    private storage: HTML5Storage
  ) {}

  // ===== Removed code for brevity ===== //

  public getter() {
    return this.clone;
  }
}

测试:

import { TestBed } from '@angular/core/testing';

// Test Case:
import { TasksData } from '../tasks-data.service';

// Dependencies:
import { SetupManagerService } from '../setup-manager.service';

let ds = [{
  'form': 'setup-device',
  'type': 'register-device',
  'text': 'Register Device',
  'icon': 'mdi-cellphone-link',
  'status': ''
}];

class SetupManagerServiceStub {
  getter() {
    return ['register-device'];
  }
}

fdescribe('Service TaskData', () => {
  let subject = TasksData;
  let setupManager;

  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        TasksData,
        { provide: SetupManagerService, useClass: SetupManagerServiceStub }
      ]
    });

    subject = TestBed.get(TasksData);
    setupManager = TestBed.get(SetupManagerService);
  });

  it('should create an instance', () => {
    expect(subject).toBeDefined();
  });

  it('should...  ', () => {
    expect(subject.getter()).toEqual(ds);
  });
});

我尝试了很多不同的例子来说明如何在线执行此操作,但大多数都不起作用,可能是因为 Angular 在最终版本之前的更改导致它们不再有效。

TasksData 服务将 SetupManagerService 作为依赖项。因此,为了避免必须添加所有 SetupManagerService 依赖项,我使用 getter 方法创建了一个 stub 类,并返回到测试 TaskData 服务所需的预期值。

首先,我不确定这是否是正确的方法。 Angular 的测试文档没有示例说明如何使用 TestBed 模块测试具有服务依赖性的服务。这是我一整天尝试的最佳工作结果。

关于这是否正确的问题只是我问题的一部分。另一个问题是 Typescript 提示我做了什么,我还没有找到解决这个问题的方法。

即使测试通过,我也会收到以下错误:

enter image description here

还有我的编辑器中这个丑陋的红色下划线警告:

enter image description here

最佳答案

这完全是一个 TypeScript 问题,更具体地说是这一行:

  let subject = TasksData;

subject(应该是 TasksData 的实例)没有充分的理由可以分配给构造函数。如果 subject 由于某种原因不会被重新分配,它就不会是 undefined,但它仍然不会是一个实例。这将导致更难调试的测试。

这里的subject是按赋值隐式类型化的,和

是一样的
  let subject: typeof TasksData = TasksData;

重新分配它

subject = new TasksData();

会导致类型错误,清楚地表明出了什么问题,

Type 'TasksData' is not assignable to type 'typeof TasksData'.

但是自TestBed.get isn't type safe and returns any ,它不会触发类型错误,并且很明显只有在访问 subject.getter 时类型才会被弄乱。

应该是

let subject: TasksData;

关于unit-testing - 测试具有服务依赖性的服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43616629/

相关文章:

json - 在配置文件 tsconfig.json 中找不到输入

c++ - Qt Creator : unit-test: is it possible to have four ways of building a code (debug, 发布、调试|发布和测试)

Angular 7 : Post request always send a null body

angular - 对使用 AngularFireAuth 和模拟 authState 的服务进行单元测试

javascript - Angular2 RC5导入第3方JS库: Showdown

typescript - Typescript中函数声明的区别

java - 不能用 mockito 模拟私有(private)方法

python - 使用 Gitlab 的 CI : QXcbConnection error 在 PyQt5 中自动化单元测试

node.js - chai 和 Eshint 的单元测试没有通过

javascript - typescript 文件中的导入模块给出错误 "cannot compile modules unless the ' --module' flag is provided"