javascript - 在服务单元测试中订阅模拟变量

标签 javascript angular unit-testing service karma-jasmine

我正在尝试对订阅数据服务变量的组件进行单元测试。我正在尝试模拟服务并覆盖组件的私有(private)数据服务变量,但我不确定如何测试模拟变量的订阅。这是我的(有限的)代码:

服务:

export class Service {
  constructor(private dataService: DataService) {
    this.dataService.newData.subscribe(data => {
      //do something
    });
  }
}

数据服务:

export class DataService {
  private source = new BehaviorSubject<any>([]);
  newData = this.source.asObservable();

  //code to update source
}

服务的单元测试:

mockDataService {
  private source = new BehaviorSubject<any>([]);
  newData = this.source.asObservable();
}

describe('Service', () => {
  beforeEach(() => {
    TestBed.configureTestingModule({
      providers: [
        Service,
        {provide: DataService, useClass: mockDataService} // is this correct?
      ]
    }).overrideComponent(Service, {
      set: {
        providers: [
          {provide: DataService, useClass: mockDataService}
        ]
      }
    }).compileComponents();
  });

  it('should register subscription', inject([Service, DataService], (service: ServiceA, mock: DataService) => { //should I be injecting the mock class?
    expect(before()).toBeTruthy();
    mock.newData.next("test"); // what's the correct way to test?
    expect(after()).toBeTruthy();
  }));
}

我是否正确覆盖?如果是这样,我如何正确测试我的组件在订阅私有(private)服务的变量时是否执行正确的操作?

谢谢!

最佳答案

首先,如果您可以在类旁边提供注释,那将会很有帮助。我假设 Service 类是一个组件,因为您在调用 TestBed.overrideComponent 时引用了它。在那种情况下,命名是困惑的。它应该至少有一个后缀“Component”(参见 Angular style guide 。)

如果 Service 实际上应该是一个服务类,那么将服务嵌套到另一个服务类中可能不是一个好的做法(see docs。)


您基本上是在要求两件事。

1。我是否需要通过 TestBed.configureTestingModule 覆盖模块的 providers 属性?

对于您上面的示例,这不是必需的。您可以轻松地从对象中省略 providers 属性。然后它看起来像

TestBed.configureTestingModule({})

在某些情况下可能需要更改提供商 - 但您的情况并非如此。

2。我应该如何正确测试服务?

您似乎混淆了集成测试和单元测试。您希望以两种方式测试服务。

首先:对服务进行单元测试 ( Angular docs )

第二:集成测试——你似乎在这里做了什么。从文档 ( link ) 开始有一个推荐的最佳实践:

it('should register subscription', () => {
    const fixture = TestBed.createComponent(Service);
    dataService = fixture.debugElement.injector.get(DataService);
    // do things
});

关于 mock.newData.next("test"),您在这里想要实现的目标并不是很清楚。此方法调用可能会给您一个 undefined function test 错误。为什么?您指的是返回 Obersvablethis.source.asObservable() .此对象没有 next 方法。你也许应该做一些关于 RxJs 的基础教程。

希望这对您有所帮助!

最好的, native

关于javascript - 在服务单元测试中订阅模拟变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47986663/

相关文章:

javascript - 如何在不模拟 AJAX 调用的情况下使用进行 AJAX 调用的函数测试 Angular Controller ?

在 Angular 中对指令 Controller 进行单元测试,而不使 Controller 成为全局的

javascript - 是否有一个网站可以生成所有可能的单词显示方式?

javascript - 在 chrome 中打印 div,css 不起作用

javascript - 如何删除此错误 "Response must contain an array at "。 "."制作下拉菜单时

javascript - 从 MongoDB 获取数据的 Node.js REST API

Angular 通用 HttpInterceptor 运行两次

angular - AKS URL 重写 Angular

javascript - Angular 4 : TypeError: this. 函数不是函数

javascript - 如何模拟在测试模块中导入的变量,它不是函数参数(使用 describe.each 并在每个测试更改模拟值时执行此操作)