Angular 测试:Mock 未按预期运行
Angular testing: Mock is not functioning as expected
我正在尝试为我的组件编写单元测试,但似乎无法让它工作。我的组件如下所示:
import { Component, OnInit } from '@angular/core';
import {ModalController} from '@ionic/angular';
import {CheckInsProvider} from '../../providers/check-ins.service';
import * as _ from 'lodash'
import {WeighInsProvider} from '../../pages/clients/client-detail/providers/weigh-ins/weigh-ins.service';
@Component({
selector: 'app-re-evaluation',
templateUrl: './re-evaluation.component.html',
styleUrls: ['./re-evaluation.component.scss'],
})
export class ReEvaluationComponent implements OnInit {
programId: number;
initialWeight: number;
endingWeight: number;
initialBodyFat: number;
endingBodyFat: number;
initialVisceralFat: number;
endingVisceralFat: number;
constructor( private modalCtrl: ModalController,
private checkInsProvider: CheckInsProvider,
private weighInsProvider: WeighInsProvider ) { }
ngOnInit() {
this.fetchWeights()
}
fetchWeights() {
console.log("here", this.weighInsProvider.findFirstWithField('current_weight'))
this.initialWeight = this.weighInsProvider.findFirstWithField('current_weight').current_weight
this.endingWeight = this.weighInsProvider.findLastWithField('current_weight').current_weight
this.initialBodyFat = this.weighInsProvider.findFirstWithField('body_fat').body_fat
this.endingBodyFat = this.weighInsProvider.findLastWithField('body_fat').body_fat
this.initialVisceralFat = this.weighInsProvider.findFirstWithField('visceral_fat').visceral_fat
this.endingVisceralFat = this.weighInsProvider.findLastWithField('visceral_fat').visceral_fat
}
dismiss(): void {
this.modalCtrl.dismiss()
}
}
我的测试是这样的:
describe('ReEvaluationComponent', () => {
let component: ReEvaluationComponent;
let fixture: ComponentFixture<ReEvaluationComponent>;
let mockGlobalsService = jasmine.createSpyObj('GlobalsService', ['base_url'])
let checkInsService: any;
let weighInsService: any;
let injector: TestBed;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ReEvaluationComponent ],
imports: [
IonicModule.forRoot(),
HttpClientTestingModule,
RouterTestingModule,
],
providers: [
WeighInsProvider,
{provide: GlobalsService, useValue: mockGlobalsService},
{provide: PurchasesService, useValue: PurchasesServiceMock},
]
}).compileComponents();
fixture = TestBed.createComponent(ReEvaluationComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
beforeEach(() => {
injector = getTestBed()
checkInsService = injector.get(CheckInsProvider)
weighInsService = injector.get(WeighInsProvider)
})
it('should create', () => {
spyOn(weighInsService, 'findFirstWithField').and.returnValue({
current_weight: 200,
visceral_fat: 20,
body_fat: 20
})
expect(component).toBeTruthy();
});
...
并且 should create
测试失败,说明:
ReEvaluationComponent should create FAILED
Failed: Cannot read properties of undefined (reading 'current_weight')
这对我来说很奇怪,因为我认为我的间谍会 return 价值:
{
current_weight: 200,
visceral_fat: 20,
body_fat: 20
}
我做错了什么?
我认为问题在于,您创建间谍为时已晚。您正在组件的 ngOnInit
中使用 current_weight
。
您的组件已创建(并将 运行 ngOnInit
)在您的第一个测试之前,您将在其中执行 spyOn
.
尝试按如下方式重构您的测试:
describe('ReEvaluationComponent', () => {
let component: ReEvaluationComponent;
let fixture: ComponentFixture<ReEvaluationComponent>;
let mockGlobalsService = jasmine.createSpyObj('GlobalsService', ['base_url'])
let checkInsService: any;
let weighInsService: any;
let injector: TestBed;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ReEvaluationComponent ],
imports: [
IonicModule.forRoot(),
HttpClientTestingModule,
RouterTestingModule,
],
providers: [
WeighInsProvider,
{provide: GlobalsService, useValue: mockGlobalsService},
{provide: PurchasesService, useValue: PurchasesServiceMock},
]
}).compileComponents();
}));
beforeEach(() => {
injector = getTestBed()
checkInsService = injector.get(CheckInsProvider)
weighInsService = injector.get(WeighInsProvider)
spyOn(weighInsService, 'findFirstWithField').and.returnValue({
current_weight: 200,
visceral_fat: 20,
body_fat: 20
});
spyOn(weighInsService, 'findLastWithField').and.returnValue({
current_weight: 200,
visceral_fat: 20,
body_fat: 20
});
});
beforeEach(() => {
fixture = TestBed.createComponent(ReEvaluationComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
...
这将允许您首先为您的服务设置模拟,然后才创建一个使用模拟服务的组件。
我正在尝试为我的组件编写单元测试,但似乎无法让它工作。我的组件如下所示:
import { Component, OnInit } from '@angular/core';
import {ModalController} from '@ionic/angular';
import {CheckInsProvider} from '../../providers/check-ins.service';
import * as _ from 'lodash'
import {WeighInsProvider} from '../../pages/clients/client-detail/providers/weigh-ins/weigh-ins.service';
@Component({
selector: 'app-re-evaluation',
templateUrl: './re-evaluation.component.html',
styleUrls: ['./re-evaluation.component.scss'],
})
export class ReEvaluationComponent implements OnInit {
programId: number;
initialWeight: number;
endingWeight: number;
initialBodyFat: number;
endingBodyFat: number;
initialVisceralFat: number;
endingVisceralFat: number;
constructor( private modalCtrl: ModalController,
private checkInsProvider: CheckInsProvider,
private weighInsProvider: WeighInsProvider ) { }
ngOnInit() {
this.fetchWeights()
}
fetchWeights() {
console.log("here", this.weighInsProvider.findFirstWithField('current_weight'))
this.initialWeight = this.weighInsProvider.findFirstWithField('current_weight').current_weight
this.endingWeight = this.weighInsProvider.findLastWithField('current_weight').current_weight
this.initialBodyFat = this.weighInsProvider.findFirstWithField('body_fat').body_fat
this.endingBodyFat = this.weighInsProvider.findLastWithField('body_fat').body_fat
this.initialVisceralFat = this.weighInsProvider.findFirstWithField('visceral_fat').visceral_fat
this.endingVisceralFat = this.weighInsProvider.findLastWithField('visceral_fat').visceral_fat
}
dismiss(): void {
this.modalCtrl.dismiss()
}
}
我的测试是这样的:
describe('ReEvaluationComponent', () => {
let component: ReEvaluationComponent;
let fixture: ComponentFixture<ReEvaluationComponent>;
let mockGlobalsService = jasmine.createSpyObj('GlobalsService', ['base_url'])
let checkInsService: any;
let weighInsService: any;
let injector: TestBed;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ReEvaluationComponent ],
imports: [
IonicModule.forRoot(),
HttpClientTestingModule,
RouterTestingModule,
],
providers: [
WeighInsProvider,
{provide: GlobalsService, useValue: mockGlobalsService},
{provide: PurchasesService, useValue: PurchasesServiceMock},
]
}).compileComponents();
fixture = TestBed.createComponent(ReEvaluationComponent);
component = fixture.componentInstance;
fixture.detectChanges();
}));
beforeEach(() => {
injector = getTestBed()
checkInsService = injector.get(CheckInsProvider)
weighInsService = injector.get(WeighInsProvider)
})
it('should create', () => {
spyOn(weighInsService, 'findFirstWithField').and.returnValue({
current_weight: 200,
visceral_fat: 20,
body_fat: 20
})
expect(component).toBeTruthy();
});
...
并且 should create
测试失败,说明:
ReEvaluationComponent should create FAILED
Failed: Cannot read properties of undefined (reading 'current_weight')
这对我来说很奇怪,因为我认为我的间谍会 return 价值:
{
current_weight: 200,
visceral_fat: 20,
body_fat: 20
}
我做错了什么?
我认为问题在于,您创建间谍为时已晚。您正在组件的 ngOnInit
中使用 current_weight
。
您的组件已创建(并将 运行 ngOnInit
)在您的第一个测试之前,您将在其中执行 spyOn
.
尝试按如下方式重构您的测试:
describe('ReEvaluationComponent', () => {
let component: ReEvaluationComponent;
let fixture: ComponentFixture<ReEvaluationComponent>;
let mockGlobalsService = jasmine.createSpyObj('GlobalsService', ['base_url'])
let checkInsService: any;
let weighInsService: any;
let injector: TestBed;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ ReEvaluationComponent ],
imports: [
IonicModule.forRoot(),
HttpClientTestingModule,
RouterTestingModule,
],
providers: [
WeighInsProvider,
{provide: GlobalsService, useValue: mockGlobalsService},
{provide: PurchasesService, useValue: PurchasesServiceMock},
]
}).compileComponents();
}));
beforeEach(() => {
injector = getTestBed()
checkInsService = injector.get(CheckInsProvider)
weighInsService = injector.get(WeighInsProvider)
spyOn(weighInsService, 'findFirstWithField').and.returnValue({
current_weight: 200,
visceral_fat: 20,
body_fat: 20
});
spyOn(weighInsService, 'findLastWithField').and.returnValue({
current_weight: 200,
visceral_fat: 20,
body_fat: 20
});
});
beforeEach(() => {
fixture = TestBed.createComponent(ReEvaluationComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
...
这将允许您首先为您的服务设置模拟,然后才创建一个使用模拟服务的组件。