Angular Jasmine fakeAsync tick不';Don’不要等待承诺得到解决
Bellow是一个我想进行单元测试的小服务(angular、jasmine、karma),其目标是下载一个文件。所以我想我应该检查是否调用了Angular Jasmine fakeAsync tick不';Don’不要等待承诺得到解决,angular,unit-testing,jasmine,karma-jasmine,Angular,Unit Testing,Jasmine,Karma Jasmine,Bellow是一个我想进行单元测试的小服务(angular、jasmine、karma),其目标是下载一个文件。所以我想我应该检查是否调用了FileSaver.saveAs。正如您在函数“second”中看到的,zip.generateAsync()返回了一个承诺,我认为通过使用fakeAsync和tick,我可以成功地等待它完成,直到代码到达expect(filesaver.saveAs)。toHaveBeenCalledTimes(1)。但通过使用console.log,我验证了函数seco
FileSaver.saveAs
。正如您在函数“second”中看到的,zip.generateAsync()
返回了一个承诺,我认为通过使用fakeAsync和tick,我可以成功地等待它完成,直到代码到达expect(filesaver.saveAs)。toHaveBeenCalledTimes(1)
。但通过使用console.log,我验证了函数second在代码检查期望值后终止,因此测试失败
为什么使用fakeAsync和tick()测试无法等待承诺得到解决
someclass.service.ts
import { Injectable } from '@angular/core';
import * as FileSaver from 'file-saver/FileSaver.js';
import * as JSZip from 'jszip/dist/jszip.min';
@Injectable()
export class SomeClass {
method2(input: any){
const blobPart = JSON.stringify(input);
const zip = new JSZip();
zip.file('data', blobPart);
zip.generateAsync({ type: 'blob' })
.then( blob => {
FileSaver.saveAs(
blob,
'randomName.dfnx'
);
});
}
method1(){
x = 'whatever';
this.method2(x);
}
}
import {TestBed, fakeAsync, tick} from '@angular/core/testing';
import {SomeClass} from './someclass.service';
const filesaver = require('file-saver/FileSaver');
describe ('Test', () => {
let service: SomeClass;
beforeEach( () => {
TestBed.configureTestingModule({
providers: [SomeClass]
});
service = TestBed.get(SomeClass);
spyOn(filesaver, 'saveAs').and.callThrough();
});
it('Test', fakeAsync( () => {
service.method1();
tick();
expect(filesaver.saveAs).toHaveBeenCalledTimes(1);
}));
});
someclass.service.spec.ts
import { Injectable } from '@angular/core';
import * as FileSaver from 'file-saver/FileSaver.js';
import * as JSZip from 'jszip/dist/jszip.min';
@Injectable()
export class SomeClass {
method2(input: any){
const blobPart = JSON.stringify(input);
const zip = new JSZip();
zip.file('data', blobPart);
zip.generateAsync({ type: 'blob' })
.then( blob => {
FileSaver.saveAs(
blob,
'randomName.dfnx'
);
});
}
method1(){
x = 'whatever';
this.method2(x);
}
}
import {TestBed, fakeAsync, tick} from '@angular/core/testing';
import {SomeClass} from './someclass.service';
const filesaver = require('file-saver/FileSaver');
describe ('Test', () => {
let service: SomeClass;
beforeEach( () => {
TestBed.configureTestingModule({
providers: [SomeClass]
});
service = TestBed.get(SomeClass);
spyOn(filesaver, 'saveAs').and.callThrough();
});
it('Test', fakeAsync( () => {
service.method1();
tick();
expect(filesaver.saveAs).toHaveBeenCalledTimes(1);
}));
});
监视你的所有函数并模仿它们:不要只监视你想测试的函数
import * as JSZip from 'jszip/dist/jszip.min';
....
spyOn(JSZip.prototype, 'generateAsync').and.returnValue(Promise.resolve('some blob'));
spyOn(JSZip.prototype, 'file');
spyOn(filesaver, 'saveAs');
单元测试应该测试单个单元,而不应该依赖于库实现。如果你模仿他们的功能,你只关注你自己的代码 您是对的,我计划这样做,但为什么在我的示例中,函数second在代码检查期望值后终止?我不知道,我从未使用过
勾选
。我想说的是,在你做出预期的时候,函数仍然在运行,因为你没有模仿任何东西,真正的函数正在运行,所以它们需要一些时间来完成