首页 > 解决方案 > 如何在 ngOnInit 中使用条件测试函数

问题描述

我想用来自 ngOnInit 中的服务的条件来测试一个函数。我尝试了很多方法,但没有成功。我有各种各样的错误。

我的组件

export class MainSectionComponent implements OnInit {    

  propertiesFrDb: PropertyPost[];

  constructor(
    private getPropertiesFrDbService: GetPropertiesFrDbService,
    private propertyWarehouseService: PropertyWarehouseService,
    private router: Router,
    config: NgbCarouselConfig,
    private userService: UserService,
    private sharedFunctionService: SharedFunctionService,
    private returnResponseAfterUserLoginService: ReturnResponseAfterUserLoginService,
    private localStorageService: LocalStorageServiceService,
    private dialogLoginService: DialogLoginService,
    @Inject(PLATFORM_ID) private platformId: Object
  ) { 
    // this.isBrowser = isPlatformBrowser(platformIds);

  }

  ngOnInit() {
    this.getPropertiesFrDb();

  }

  getPropertiesFrDb() {
    if (this.propertyWarehouseService.currentValuesProperties) {
      this.propertyWarehouseService.getPropertyHome$.subscribe(
        prop => {
          console.log(prop);

         return this.propertiesFrDb = prop
        }
      )
    } else {

      this.getPropertiesFrDbService.getHomeProperties()
        .subscribe(property => {
          // console.log(property['results']);
          this.propertyWarehouseService.setPropertiesHome(property['results'])
         return   this.propertiesFrDb = property['results']

        },

        )
    }
  }

我想测试 我想测试案例并检查被调用并检查this.getPropertiesFrDb()的值ngOnInitthis.propertyWarehouseService.currentValuesProperties !== ''this.getPropertiesFrDbService.getHomeProperties()propertiesFrDb

和我的spec.ts文件

import { async, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';

import { MainSectionComponent } from './home-properties.component';
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { MaterialModule } from 'src/app/material/material.module';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { GetPropertiesFrDbService } from 'src/app/services/getPropertiesFromDb/get-properties-fr-db.service';
import { MOCKPROPERTIES, MockPropertyWarehouseService } from 'src/app/mocks/property-post';
import { NgxPaginationModule, PaginatePipe } from 'ngx-pagination';
import { PropertyWarehouseService } from 'src/app/services/propertyWarehouse/property-warehouse.service';
import { BsDropdownModule } from 'ngx-bootstrap';
import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
import { StorageServiceModule } from 'angular-webstorage-service';
import { of } from 'rxjs/internal/observable/of';

fdescribe('MainSectionComponent', () => {
  let component: MainSectionComponent;
  let fixture: ComponentFixture<MainSectionComponent>;
  const PROPERTYMODEL = MOCKPROPERTIES;
  const spyPropertyWarehouseService = jasmine.createSpyObj('spypropertyWarehouseService', ['currentValuesProperties', 'getPropertyHome$']);


  beforeEach(async(() => {
    TestBed.configureTestingModule({
      imports: [
        MaterialModule,
        HttpClientTestingModule,
        RouterTestingModule.withRoutes([]),
        NgxPaginationModule,
        BsDropdownModule.forRoot(),
        NgbModule,
        StorageServiceModule,


      ],
      declarations: [
        MainSectionComponent,

      ],
      providers: [
        {
          provide: PropertyWarehouseService,
          useValue:  spyPropertyWarehouseService
      }

      ],
      schemas: [CUSTOM_ELEMENTS_SCHEMA],

    })
      .compileComponents();

  }));

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

  });


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

  it('Should get  propertiesFrDb from GetPropertiesFrDbService', async(() => {
    spyPropertyWarehouseService.currentValuesProperties.and.returnValue(PROPERTYMODEL);
    spyPropertyWarehouseService.getPropertyHome$.and.returnValue(of(PROPERTYMODEL));
    expect(component.propertiesFrDb).toBe(PROPERTYMODEL);

    console.log('spy',spyPropertyWarehouseService);

  }));

});

标签: javascriptangulartypescriptkarma-jasmineangular8

解决方案


尝试创建一个存根,如下所示:

export class PropertyWarehouseServiceStub{
   currentValuesProperties = '';
   getPropertyHome$ = new BaheviorSubject<any>('someObj');
   setPropertiesHome(){  }

}

export class GetPropertiesFrDbServiceStub{
   getHomeProperties(){
     return of({results: 'val'})
   }
}

component文件中使服务在构造函数中公开,以便我们可以覆盖它的一些行为:

constructor(...,
   public propertyWarehouseService: PropertyWarehouseService, 
   public getPropertiesFrDbService: GetPropertiesFrDbService,
   ....)

并在spec文件中:

      providers: [
        {
          provide: PropertyWarehouseService,
          useClass:  PropertyWarehouseServiceStub
        },{
          provide: GetPropertiesFrDbService,
          useClass:  GetPropertiesFrDbServiceStub
        }
      ],

......
....
..
it('should call getPropertiesFrDb() in ngOnInit',()=>{
     spyOn(component,'getPropertiesFrDb').and.callThrough();
     component.ngOnInit();
     expect(component.getPropertiesFrDb).toHaveBeenCalled();
})

it('inside getPropertiesFrDb() should call getPropertiesFrDbService.getHomeProperties() when "propertyWarehouseService.currentValuesProperties" is empty,()=>{
  spyOn(component.getPropertiesFrDbService,'getHomeProperties').and.callThrough();
  spyOn(component.propertyWarehouseService,'setPropertiesHome').and.callThrough();
  component.getPropertiesFrDb();
  expect(component.getPropertiesFrDbService.getHomeProperties).toHaveBeenCalled();
  expect(component.propertyWarehouseService.setPropertiesHome).toHaveBeenCalledWith('val');
  expect(component.propertiesFrDb).toBe('someObj'); 
})

it('inside getPropertiesFrDb() should not call getPropertiesFrDbService.getHomeProperties() when "propertyWarehouseService.currentValuesProperties" is NOT empty,()=>{
  component.propertyWarehouseService.currentValuesProperties = 'Not empty';
  spyOn(component.getPropertiesFrDbService,'getHomeProperties').and.callThrough();
  spyOn(component.propertyWarehouseService,'setPropertiesHome').and.callThrough();
  component.getPropertiesFrDb();
  expect(component.getPropertiesFrDbService.getHomeProperties).not.toHaveBeenCalled();
  expect(component.propertyWarehouseService.setPropertiesHome).not.toHaveBeenCalledWith('val');
  expect(component.propertiesFrDb).toBe('val');
})

您可以参考我在 Karma-jasmine 上撰写的这篇介绍文章,其中包含多个测试用例的更多文章参考。

这与您正在寻找的非常相似。我打算再写一些文章,以防你想关注。


另外,我不知道你为什么return在里面使用如下getPropertiesFrDb()

return this.propertiesFrDb = prop

这是没有用的,因为这个函数的任何值都没有分配给里面的任何变量ngOnInit


推荐阅读