javascript - 如何在 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()
的值ngOnInit
this.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);
}));
});
解决方案
尝试创建一个存根,如下所示:
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
。
推荐阅读
- kubernetes - Kubernetes 如何自动扩展节点?
- linux - 如何在通过/bin/bash打开的shell中执行linux命令
- ios - 为什么 Realm Set 对象是随机工作的?
- c# - 使用动作
委托具有参数化构造函数的类 - laravel - 用于显示结果的计算的 WhereIN 数据
- javascript - Cordova 插件文件未从 fileEntry 返回文件
- xaml - System.TypeInitializationException Xamarin CarouselView
- javascript - 如何修复模态弹出关闭按钮在 Wordpress 上的显示部分?
- angular - 2 方式绑定 ngModel 更改也反映在其分配的临时变量中(在页面加载时分配)
- c# - 我可以像这样从两个 texbox 中获得不匹配的值吗?