测试使用服务的组件以获取一些数据

时间:2018-07-12 17:56:19

标签: angular jasmine karma-jasmine karma-runner

我有一个服务,该服务从商店中读取一些数据,然后根据该数据返回布尔值Observable。是:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Store } from '@ngrx/store';
import * as _ from 'lodash';

@Injectable()
export class SomeService {

   enabledObv$: Observable<any>;

   constructor(private store: Store<AppState>) {
      enabledObv$ = this.store.select<any>(‘some-store’);
   }

   checkIfExists$(someData: any): Observable<boolean> {

   return this.enabledObv$.map(
       (dataClass: any) => {
           return _.includes(dataClass.someField, someData);
       });
   }

}

现在,此服务正在组件中使用。具体来说,我正在针对组件中的某些值使用checkIfExists$方法。

运行测试时出现错误:

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { rootReducer } from '../../../../store/root-reducer';
import { SomeComponent } from ‘./some.component';
import { SomeService } from '../../../../shared/services/config/some.service';

describe(‘SomeComponent’, () => {
    let component: SomeComponent;
    let fixture: ComponentFixture<SomeComponent>;

    beforeEach(async(() => {

    TestBed.configureTestingModule({
        declarations: [SomeComponent],
        imports: [// modules that the component is using],
        providers: [SomeService]
    }).compileComponents();

    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(SomeComponent);
        component = fixture.componentInstance;
        fixture.detectChanges();

    });

    it('should create', () => {
        expect(component).toBeTruthy();
    });
});

根据建议,添加组件代码:

export class SomeComponent implements OnInit, OnDestroy {

    ifExistsA$: Observable<boolean>;

// ------------------------------------------------------------------------------------
    constructor(private someService: SomeService, private store: Store<AppState>) {
    }

    ngOnInit() {
        this.initAEnabled();
    }

     private initAEnabled(): void {
        this.ifExistsA$ =
            this.someService.checkIfExists$(valueToBeChecked);
     }

}

现在在HTML文件中使用ifExistsA $和异步管道来显示内容。访问类似于:ifExistsA $ |异步

基本上,我正在使用ifExistsA$来显示一些数据,具体取决于它在商店中的存在。

运行此测试时出现错误:

TypeError: Cannot read property 'dataClass' of undefined

我要去哪里错了?
除了将其添加为提供程序之外,我还需要对服务做些什么?
我要嘲笑吗?
如果必须模拟它,是否需要为dataClass提供一些价值?
如果是这样,那我该怎么办?

1 个答案:

答案 0 :(得分:0)

您的服务似乎是问题所在。您正在向测试组件提供真正的服务,但是没有正确实例化这就是为什么该方法失败的原因。

您可以执行以下任一操作:

  1. 创建一个存根服务,该存根服务具有公共方法的存根实现,然后将其提供给组件测试以代替真实服务。看起来像providers: [ {provide: SomeService, useValue: new StubService()}]

  2. checkIfExists$上的beforeEach块中进行监视,因此不会调用真正的实现。

它看起来像:

import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { rootReducer } from '../../../../store/root-reducer';
import { SomeComponent } from ‘./some.component';
import { SomeService } from '../../../../shared/services/config/some.service';

describe('SomeComponent', () => {
    let component: SomeComponent;
    let fixture: ComponentFixture<SomeComponent>;
    let service: SomeService;

    beforeEach(async(() => {

    TestBed.configureTestingModule({
        declarations: [SomeComponent],
        imports: [],
        providers: [SomeService]
    }).compileComponents();

    }));

    beforeEach(() => {
        fixture = TestBed.createComponent(SomeComponent);
        component = fixture.componentInstance;
        service = TestBed.get(SomeService);
        spyOn(service, 'checkIfExists$');
        fixture.detectChanges();

    });

    it('should create', () => {
        expect(component).toBeTruthy();
    });
});

我希望有帮助。