如何测试异步函数中设置的变量?
How to test a variable setted in an async function?
我试图在执行异步函数后测试变量的值,但是当我尝试读取它时它是一个空数组(变量应该有一个包含对象的数组),我也把一些 console.log() 在函数内部,它工作正常。
这是我第一次使用 Jasmine 和 Karma,所以任何帮助都很好。
我组件里面的函数
async refresh() {
let requestUserProfile;
let data
// this._fuseSplashScreenService.hide();
// this.showLoading('Cargando documentos...');
//requestUserProfile = this.getUserProfile();
this._restService.getDocumentsLimit(100, 1, undefined).subscribe((documents: any) => {
//Here is just a part of this function
this.moreData = documents.data;
});
}
变量 moreData 是我一直试图测试的变量。
测试代码;
describe('DashboardComponent', () => {
let component: DashboardComponent;
let fixture: ComponentFixture<DashboardComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [HomeModule, HttpClientModule, RouterTestingModule, NoopAnimationsModule, MatDialogModule ],
declarations: [ DashboardComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(DashboardComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
//This is the one
it('should have info', async () =>{
await component.refresh();
console.log(component.moreData);
//expect(component.moreData).not.toBe(null)
})
});
问题不在于异步函数之类的。在你的测试脚本中,你需要做的是模拟服务,return一些值,然后它会自动覆盖那个变量。
这是您需要做的:
////////////////// Use Injectable and create a mock-service;
@Injectable()
class MockService extends RestService {
////////////////////// Mock your method here
getDocumentsLimit() {
return of({
data: {
// You know what response comes here, so use that here;
someData: 'someDataValue'
}
}
}
}
describe('DashboardComponent', () => {
let component: DashboardComponent;
let fixture: ComponentFixture<DashboardComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [HomeModule, HttpClientModule, RouterTestingModule, NoopAnimationsModule, MatDialogModule ],
declarations: [ DashboardComponent ],
///////////////// ADD THIS LINE IN THE PROVIDERS /////////////
providers: [
{
provide: RestService,
useClass: MockService
}
]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(DashboardComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
//This is the one
////////////////////// YOUR TEST CASE WILL BECOME THIS
it('should have info', () =>{
spyOn(component, 'refresh').and.callThrough();
component.refresh();
expect(component.refresh).toHaveBeenCalled();
})
});
_restService.getDocumentsLimit(...) 可能 returns 一个异步可观察对象(我假设是 http 调用),这意味着 refresh() returns 立即并且订阅的回调方法是预期的将来有时会被调用(当结果从 http 调用到达时)。但是,测试执行在回调有机会被调用之前终止,因此分配给 this.moreData 永远不会发生。
不希望出现您对测试失去控制的情况。解决方案是摆脱可能会干扰您测试的依赖项,或者更好地说让它们由 mocking.
控制
因此,在您的测试中,您应该模拟 getDocumentsLimit(...) 方法,但这里的关键是让它 return 成为一个带有假数据的同步可观察对象,然后期望 this.moreData 保持那个假数据。
我试图在执行异步函数后测试变量的值,但是当我尝试读取它时它是一个空数组(变量应该有一个包含对象的数组),我也把一些 console.log() 在函数内部,它工作正常。
这是我第一次使用 Jasmine 和 Karma,所以任何帮助都很好。
我组件里面的函数
async refresh() {
let requestUserProfile;
let data
// this._fuseSplashScreenService.hide();
// this.showLoading('Cargando documentos...');
//requestUserProfile = this.getUserProfile();
this._restService.getDocumentsLimit(100, 1, undefined).subscribe((documents: any) => {
//Here is just a part of this function
this.moreData = documents.data;
});
}
变量 moreData 是我一直试图测试的变量。
测试代码;
describe('DashboardComponent', () => {
let component: DashboardComponent;
let fixture: ComponentFixture<DashboardComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [HomeModule, HttpClientModule, RouterTestingModule, NoopAnimationsModule, MatDialogModule ],
declarations: [ DashboardComponent ]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(DashboardComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
//This is the one
it('should have info', async () =>{
await component.refresh();
console.log(component.moreData);
//expect(component.moreData).not.toBe(null)
})
});
问题不在于异步函数之类的。在你的测试脚本中,你需要做的是模拟服务,return一些值,然后它会自动覆盖那个变量。
这是您需要做的:
////////////////// Use Injectable and create a mock-service;
@Injectable()
class MockService extends RestService {
////////////////////// Mock your method here
getDocumentsLimit() {
return of({
data: {
// You know what response comes here, so use that here;
someData: 'someDataValue'
}
}
}
}
describe('DashboardComponent', () => {
let component: DashboardComponent;
let fixture: ComponentFixture<DashboardComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [HomeModule, HttpClientModule, RouterTestingModule, NoopAnimationsModule, MatDialogModule ],
declarations: [ DashboardComponent ],
///////////////// ADD THIS LINE IN THE PROVIDERS /////////////
providers: [
{
provide: RestService,
useClass: MockService
}
]
})
.compileComponents();
});
beforeEach(() => {
fixture = TestBed.createComponent(DashboardComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
//This is the one
////////////////////// YOUR TEST CASE WILL BECOME THIS
it('should have info', () =>{
spyOn(component, 'refresh').and.callThrough();
component.refresh();
expect(component.refresh).toHaveBeenCalled();
})
});
_restService.getDocumentsLimit(...) 可能 returns 一个异步可观察对象(我假设是 http 调用),这意味着 refresh() returns 立即并且订阅的回调方法是预期的将来有时会被调用(当结果从 http 调用到达时)。但是,测试执行在回调有机会被调用之前终止,因此分配给 this.moreData 永远不会发生。
不希望出现您对测试失去控制的情况。解决方案是摆脱可能会干扰您测试的依赖项,或者更好地说让它们由 mocking.
控制因此,在您的测试中,您应该模拟 getDocumentsLimit(...) 方法,但这里的关键是让它 return 成为一个带有假数据的同步可观察对象,然后期望 this.moreData 保持那个假数据。