用例:对于我的 angularJS(1.6.4) 应用程序,我正在用 jasmine 编写单元测试。
在我的测试用例中,我调用了一个 poll() 函数,该函数不断使用 $interval 重复调用另一个函数 CheckTaskStatus()。我正在监视 CheckTaskStatus() 并想检查它是否被调用了一定次数。所以在调用 poll() 之后,我希望能够等待一段时间,然后检查使用 expect() 调用 CheckTaskStatus() 的次数。
问题:我一直无法找到一种方法让 jasmine 在调用 poll() 之后和 expect() 之前等待。
在 poll() 之后,我尝试使用以下选项,但这些选项不会导致茉莉花入睡:
导出类轮询 { public static $inject = ['$q', '$http', '$interval'];
constructor(private $q: ng.IQService, private $http, private $interval) {}
public poll(interval: number, pollFn: () => ng.IPromise<any>, until?: (any) => boolean, cancel?: ng.IPromise<any>) {
let intervalPromise = null;
const done = this.$q.defer();
const intervalFn = () => {
pollFn().then((pollFnResult) => {
if (until && until(pollFnResult)) {
this.$interval.cancel(intervalPromise);
done.resolve();
}
}).catch(() => {});
};
// Set up an interval to execute the pollFunction
intervalPromise = this.$interval(intervalFn, interval);
intervalPromise.catch(() => {});
intervalFn();
if (cancel) {
cancel.then(() => {
this.$interval.cancel(intervalPromise);
done.resolve();
})
.catch(() => {});
}
return done.promise;
}
Run Code Online (Sandbox Code Playgroud)
}
导出默认 angular.module('myPolling', []) .service('polling', Polling).name;
茉莉花测试
constructor(private $q: ng.IQService, private $http, private $interval) {}
public poll(interval: number, pollFn: () => ng.IPromise<any>, until?: (any) => boolean, cancel?: ng.IPromise<any>) {
let intervalPromise = null;
const done = this.$q.defer();
const intervalFn = () => {
pollFn().then((pollFnResult) => {
if (until && until(pollFnResult)) {
this.$interval.cancel(intervalPromise);
done.resolve();
}
}).catch(() => {});
};
// Set up an interval to execute the pollFunction
intervalPromise = this.$interval(intervalFn, interval);
intervalPromise.catch(() => {});
intervalFn();
if (cancel) {
cancel.then(() => {
this.$interval.cancel(intervalPromise);
done.resolve();
})
.catch(() => {});
}
return done.promise;
}
Run Code Online (Sandbox Code Playgroud)
AngularJS 异步代码和任意 JS 代码在 Jasmine 中的测试方式不同。
AngularJS 服务是专门为使测试同步而设计的,包括$interval:
在测试中,您可以使用 $interval.flush(millis) 以毫秒为单位向前移动并触发计划在该时间内运行的任何函数。
所以它是:
let cancel = this.$q.defer();
this.polling.poll(100, pollObj.pollFn, () => false, cancel.promise);
$interval.flush(1050);
expect(pollObj.pollFn).toHaveBeenCalledTimes(10);
Run Code Online (Sandbox Code Playgroud)
在涉及非 Angular 异步单元的测试中是不同的。应该使用Jasmine 时钟 API。它修补内置计时器功能,以便与 Jasminetick方法同步执行它们。
beforeEach(() => {
jasmine.clock().install();
});
afterEach(() => {
jasmine.clock().uninstall();
});
it('...', () => {
SleepForASecond().then(() => {
expect(1).toBe(0);
});
jasmine.clock().tick(1050);
});
Run Code Online (Sandbox Code Playgroud)
Jasmine 2.7添加了对 promise 和async函数的支持。这允许无缝测试基于承诺的功能,但承诺会产生真正的延迟并导致异步测试:
it('...', async () => {
await SleepForASecond();
expect(1).toBe(0);
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9236 次 |
| 最近记录: |