在测试在Jasmine单元测试中返回promise的方法时遇到一个奇怪的问题。我有以下课程:
import http = require('http');
import https = require('https');
import fs = require('fs');
export default class ImageDownloader {
constructor(protected downloadPath:string) {}
async download(url: string): Promise<string> {
return new Promise<string>((resolve, reject) => {
let file = fs.createWriteStream(this.downloadPath, { autoClose: true });
let schema:any = url.startsWith('https') ? https : http;
schema.get(url, (response:fs.ReadStream) => {
response.pipe(file).on('finish', () => resolve(this.downloadPath));
}).on('error', (error) => reject(error));
});
}
}
它将图像下载到构造函数中给出的下载路径,然后在文件写入磁盘后使用该下载路径解析promise。
我写过一个Jasmine单元测试:
import fs = require('fs');
import http = require('http');
import ImageDownloader from '../../src/Image/ImageDownloader';
describe('Image Downloader', () => {
describe('download()', () => {
it('returns the path to the downloaded image', done => {
spyOn(http, 'get').and.callFake((url, cb) => {
cb(fs.createReadStream(__dirname+'/../assets/elephpant.png'));
});
let imageDownloader = new ImageDownloader('/tmp/image');
imageDownloader.download('http://foo.bar/bazz.jpg').then((path) => {
expect(path).toEqual('/tmp/image');
done();
});
});
});
});
在这个测试中,我模拟了Node http
模块,以便返回我自己伪造的#34; HTTP响应&#34;。请记住Node的IncomingMessage
类(通常作为来自http.get()
的响应返回的内容)实现了可读的流接口,所以我只是用{{返回我自己的可读流1}}。
运行此测试时,它只会超时,因为承诺永远不会得到解决:
fs.createReadStream()
然而,奇怪的是,如果我改变解析对此承诺的F
Failures:
1) Image Downloader download() returns the path to the downloaded image
1.1) Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
方法的部分:
download()
我看到了这个输出:
response.pipe(file).on('finish', () => console.log('the promise would normally be resolved here'));
因此,当我们调用诺言时,我们显然已经接触到了这一部分。这就像我打电话给the promise would normally be resolved here
F
Failures:
1) Image Downloader download() returns the path to the downloaded image
1.1) Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
但承诺因某种原因无法解决。