如何对调用可观察服务的组件进行单元测试

时间:2016-04-25 18:34:39

标签: unit-testing jasmine angular rxjs

我正在尝试对订阅了可观察服务的函数进行单元测试。不知道从哪里开始。

组件功能我正在尝试进行单元测试:

  register() {
    this._registrationService.registerUser(this.form.value)
        .subscribe(data => {
          if (data) {
            this.errorMessage = '';
            this.successMessage = 'Account successfully created';
          } else {
            this.errorMessage = 'Error';
            this.successMessage = '';
          }
        },
        error => {
          this.errorMessage = error;
          this.successMessage = '';
        });
  }

服务:

  registerUser(user) {
    const registerUrl = this.apiUrl;

    return this._http.post(registerUrl, JSON.stringify(user), { headers: this.apiHeaders })
      .map(res => res.json())
      .catch(this._handleError);
  }

3 个答案:

答案 0 :(得分:1)

我会使用RegistrationService模拟Observable.of服务以返回数据。

class MockRegistrationService {
  registerUser(data: any) {
    return Observable.of({});
  }
}

在单元测试中,您需要通过模拟的覆盖RegistrationService服务:

describe('component tests', () => {
  setBaseTestProviders(TEST_BROWSER_PLATFORM_PROVIDERS,
                   TEST_BROWSER_APPLICATION_PROVIDERS);

  var service = new MockRegistrationService();

  beforeEachProviders(() => [
    provide(RegistrationService, { useValue: service })
  ]);

  it('should open', 
    injectAsync([TestComponentBuilder], (tcb: TestComponentBuilder) => {
      return tcb
      .createAsync(RegistrationComponent)
      .then(fixture => {
        let elt = fixture.nativeElement;
        let comp: RegistrationComponent = fixture.componentInstance;

        fixture.detectChanges();

        expect(comp.successMessage).toEqual('Account successfully created');
        expect(comp.errorMessage).toEqual('');
      });
    });
  }));
});

有关详细信息,请参阅此plunkr:https://plnkr.co/edit/zTy3Ou?p=info

答案 1 :(得分:0)

在单元测试中,只有一个“真实”对象:您正在测试的对象。应该嘲笑依赖性,就像其他对象和函数一样。

模拟正在创建模拟真实对象行为的对象。 本主题包含更多信息:What is Mocking?

我对Jasmine并不熟悉,但在这里我找到了一篇可能有用的文章: https://volaresystems.com/blog/post/2014/12/10/Mocking-calls-with-Jasmine

答案 2 :(得分:0)

如果有人想知道结果如何,则发布我的工作测试/规范文件:

测试文件:

import {
  it,
  inject,
  injectAsync,
  describe,
  beforeEachProviders,
  TestComponentBuilder,
  resetBaseTestProviders,
  setBaseTestProviders
} from 'angular2/testing';

import {TEST_BROWSER_PLATFORM_PROVIDERS, TEST_BROWSER_APPLICATION_PROVIDERS} from 'angular2/platform/testing/browser';
import {Observable} from 'rxjs/Rx';
import {provide} from 'angular2/core';
import {RootRouter} from 'angular2/src/router/router';
import {Location, Router, RouteRegistry, ROUTER_PRIMARY_COMPONENT} from 'angular2/router';
import {SpyLocation} from 'angular2/src/mock/location_mock';

import {RegistrationService} from '../shared/services/registration';
import {Register} from './register';
import {App} from '../app';

class MockRegistrationService {
  registerUser(user) {
    return Observable.of({
      username: 'TestUser1',
      password: 'TestPassword1'
    });
  }
}

describe('Register', () => {
  resetBaseTestProviders();
  setBaseTestProviders(TEST_BROWSER_PLATFORM_PROVIDERS, TEST_BROWSER_APPLICATION_PROVIDERS);

  let registrationService = new MockRegistrationService();

  beforeEachProviders(() => [
    Register,
    RouteRegistry,
    provide(RegistrationService, { useValue: registrationService }),
    provide(Location, {useClass: SpyLocation}),
    provide(Router, {useClass: RootRouter}),
    provide(ROUTER_PRIMARY_COMPONENT, {useValue: App})
  ]);


  it('should open', injectAsync([TestComponentBuilder], (tcb) => {
      return tcb
        .createAsync(Register)
        .then(fixture => {
          let registerComponent = fixture.componentInstance;

          fixture.detectChanges();

          registerComponent.register({
            username: 'TestUser1',
            password: 'TestPassword1'
          });

          expect(registerComponent.successMessage).toEqual('Account successfully created');
          expect(registerComponent.errorMessage).toEqual('');
        });
    }));

});