【发布时间】:2018-12-20 04:44:06
【问题描述】:
我有一个打字稿模块,它使用浏览器的原生 Blob。我想在节点中测试它,所以我需要同一个模块来查看全局假 Blob 实现。一个非常简单的假 blob 实现对我有用
class Blob {
parts?: any;
options?: any;
constructor(parts: any, options?: any) {
this.parts = parts;
this.options = options;
}
getType():string {
return options.type; // I know, hacky by just a demo
}
}
但是如何将它注入节点的全局命名空间,以便我在浏览器中运行测试时通常在浏览器中运行的代码可以看到它?
换句话说,假设我有一个预计会返回本机浏览器Blob的类
export class BlobMaker {
static makeTextBlob(text):Blob {
return new Blob([text], {type: 'text/text'});
}
}
现在我想在节点(而不是浏览器)中测试它
import { BlobMaker } from '../src/blob-maker';
import * as expect from 'expect';
describe('BlobMaker', () => {
it('makes a text blob', () => {
const blob = BlobMaker.makeTextBlob('foo');
expect(blob.getType()).equalTo('text/text');
});
});
编译失败,因为节点中不存在Blob。
显然我可以通过添加来声明它存在?
export interface Global extends NodeJS.Global {
Blob: Blob;
}
但我仍然需要在上面注入我的假 Blob 类,以便我正在测试的代码将使用它。有没有办法做到这一点,或者我应该以其他方式解决这个问题?
我似乎无法将 Blob 抽象为某种接口,因为我需要 makeTextBlob 的签名才能成为真正的原生浏览器 Blob 而不是某种自定义类型。
我想我知道我可以通过测试将 Blob 工厂深入到我的库中。经过这么深的 Blob 工厂似乎有点矫枉过正。我实际上是通过打字稿抱怨的。我认为是因为它认为BlobMaker.makeBlob 返回的类型不同
这是代码
let makeBlob = function(...args):Blob {
return new Blob(...args);
};
export function setMakeBlob(fn):void {
makeBlob = fn;
};
export class BlobMaker {
static makeTextBlob(text):Blob {
return makeBlob([text], {type: 'text/text'});
}
}
然后在测试中
import { BlobMaker, setMakeBlob } from '../src/blob-maker';
import { Blob } from "./fake-blob';
import * as expect from 'expect';
describe('BlobMaker', () => {
it('makes a text blob', () => {
setMakeBlob(function(parts, options) {
return new Blob();
});
const blob = BlobMaker.makeTextBlob('foo');
expect(blob.getType()).equalTo('text/text'); // ERROR!
});
});
我收到一个错误,Blob 上没有 getType 方法。我猜 TS 认为 BlobMaker.makeTextBlob 返回的 Blob 是原生的。我试着投射它
const blob = BlobMaker.makeTextBlob('foo') as Blob;
但它也不喜欢那样。
如果我可以将我的 Blob 类注入到 node.js 中的全局命名空间中,这似乎都可以解决。那么,我该怎么做呢?
【问题讨论】:
-
我的印象是
/// <referenceing 来自BlobMaker模块的.d.ts文件就足够了,你试过了吗? -
抱歉,这是我的第一次打字体验,但这将如何帮助 BlobMaker 找到
Blob? -
哦等等我看错了,你的
Blob是class,而不是interface(这应该意味着它在一个普通的.ts文件中。你的@ 987654352@ 模块应该是import Blob from './blob'或任何导出它的地方。即使它被理解为一个全局变量,但在使用 TypeScript 时将它作为模块的一部分处理要容易得多。 -
我不确定这有什么帮助。此代码仍然需要在浏览器中运行并返回浏览器原生
Blob(更新问题)。我只想在节点中运行的测试中使用假 blob 对其进行测试。 -
我自己还不是特别精通 TypeScript,但是看看这里的上下文,我认为您应该考虑模拟
Blob模块。我发现 this answer 可能对你有用也可能没用,但你可以做的是重写Blob所在的文件以附加到global,前提是global.Blob上没有定义任何内容。
标签: typescript