【问题标题】:How to unit test a component that calls observable service如何对调用可观察服务的组件进行单元测试
【发布时间】:2016-04-25 18:34:39
【问题描述】:

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

我正在尝试单元测试的组件函数:

  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);
  }

【问题讨论】:

    标签: unit-testing jasmine angular rxjs


    【解决方案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

    【讨论】:

      【解决方案2】:

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

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

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

      【讨论】:

        【解决方案3】:

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

        测试文件:

        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('');
                });
            }));
        
        });
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-04-25
          • 1970-01-01
          • 2021-09-29
          • 2018-01-02
          • 1970-01-01
          • 2018-04-28
          • 1970-01-01
          • 2018-12-11
          相关资源
          最近更新 更多