当它具有相同的命名空间名称时模拟库函数
Mocking library function when it has the same namespace name
类似于 ,我正在尝试使用 sinon
模拟外部库。但是,该库使用相同的名称 FastGlob
.
导出两个函数和一个命名空间
我对函数重载有基本的了解,但我不确定命名空间如何与函数重载一起工作,或者这个问题是否相关。
不管怎样,我想模拟第一个函数定义,但是 sinon
看到了命名空间
declare function FastGlob(source: PatternInternal | PatternInternal[], options: OptionsInternal & EntryObjectPredicate): Promise<EntryInternal[]>;
这是库定义文件
import { Options as OptionsInternal } from './settings';
import { Entry as EntryInternal, FileSystemAdapter as FileSystemAdapterInternal, Pattern as PatternInternal } from './types';
declare function FastGlob(source: PatternInternal | PatternInternal[], options: OptionsInternal & EntryObjectPredicate): Promise<EntryInternal[]>;
declare function FastGlob(source: PatternInternal | PatternInternal[], options?: OptionsInternal): Promise<string[]>;
declare namespace FastGlob {
type Options = OptionsInternal;
type Entry = EntryInternal;
type Task = taskManager.Task;
type Pattern = PatternInternal;
type FileSystemAdapter = FileSystemAdapterInternal;
function sync(source: PatternInternal | PatternInternal[], options: OptionsInternal & EntryObjectPredicate): EntryInternal[];
function sync(source: PatternInternal | PatternInternal[], options?: OptionsInternal): string[];
function stream(source: PatternInternal | PatternInternal[], options?: OptionsInternal): NodeJS.ReadableStream;
function generateTasks(source: PatternInternal | PatternInternal[], options?: OptionsInternal): Task[];
function isDynamicPattern(source: PatternInternal, options?: OptionsInternal): boolean;
function escapePath(source: PatternInternal): PatternInternal;
}
export = FastGlob;
我试过使用以下测试的变体,但 TS 抱怨它只能在命名空间(同步、流等)中找到函数。删除函数的字符串名称会导致不同的问题。
import * as FastGlob from 'fast-glob';
import { stub, SinonStub } from "sinon";
import { Pattern, Entry, Options } from "fast-glob";
(stub(FastGlob, "FastGlob") as unknown as SinonStub<[s: Pattern | Pattern[], o: Options], Promise<Entry[]>>).resolves([{test: '/test/'} as unknown as Entry])
应用程序代码是这样使用的
import * as glob from 'fast-glob';
const paths: Array<string> = await glob('./my/glob/**/*.ts', { absolute: true });
你需要额外的模块来存根 fast-glob,因为它定义的方式。欲了解更多信息,您可以查看此 sinon issue.
如果你可以使用额外的模块,我可以给你举个例子:proxyquire.
我有这个glob.ts。
// File: glob.ts
import glob from 'fast-glob';
async function getPaths(input: string): Promise<Array<glob.Entry|string>> {
return glob(input, { absolute: true });
}
export { getPaths };
使用规范文件进行测试:
// File: glob.spec.ts
import * as FastGlob from 'fast-glob';
import sinon from 'sinon';
import proxyquire from 'proxyquire';
import { expect } from 'chai';
describe('Glob', () => {
const fakeInput = './node_modules/**/settings.js';
it('getPaths using first fast-glob definition', async () => {
const fakeResult = [{ test: '/test/' } as unknown as FastGlob.Entry];
const fakeFunc = sinon.fake.resolves(fakeResult);
// Create stub using proxyquire.
const glob = proxyquire('./glob', {
'fast-glob': sinon.fake.resolves(fakeResult),
});
const paths = await glob.getPaths(fakeInput);
expect(paths).to.deep.equal(fakeResult);
expect(fakeFunc.calledOnceWithExactly(fakeInput));
})
it('getPaths using second fast-glob definition', async () => {
const fakeResult = ['/test/'];
const fakeFunc = sinon.fake.resolves(fakeResult);
// Create stub using proxyquire.
const glob = proxyquire('./glob', {
'fast-glob': sinon.fake.resolves(fakeResult),
});
const paths = await glob.getPaths(fakeInput);
expect(paths).to.deep.equal(fakeResult);
expect(fakeFunc.calledOnceWithExactly(fakeInput));
})
});
当你运行它从终端使用 ts-mocha 和 nyc 时:
$ npx nyc ts-mocha glob.spec.ts
Glob
✔ getPaths using first fast-glob definition (137ms)
✔ getPaths using second fast-glob definition
2 passing (148ms)
--------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
--------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
glob.spec.ts | 100 | 100 | 100 | 100 |
glob.ts | 100 | 100 | 100 | 100 |
--------------|---------|----------|---------|---------|-------------------
类似于 sinon
模拟外部库。但是,该库使用相同的名称 FastGlob
.
我对函数重载有基本的了解,但我不确定命名空间如何与函数重载一起工作,或者这个问题是否相关。
不管怎样,我想模拟第一个函数定义,但是 sinon
看到了命名空间
declare function FastGlob(source: PatternInternal | PatternInternal[], options: OptionsInternal & EntryObjectPredicate): Promise<EntryInternal[]>;
这是库定义文件
import { Options as OptionsInternal } from './settings';
import { Entry as EntryInternal, FileSystemAdapter as FileSystemAdapterInternal, Pattern as PatternInternal } from './types';
declare function FastGlob(source: PatternInternal | PatternInternal[], options: OptionsInternal & EntryObjectPredicate): Promise<EntryInternal[]>;
declare function FastGlob(source: PatternInternal | PatternInternal[], options?: OptionsInternal): Promise<string[]>;
declare namespace FastGlob {
type Options = OptionsInternal;
type Entry = EntryInternal;
type Task = taskManager.Task;
type Pattern = PatternInternal;
type FileSystemAdapter = FileSystemAdapterInternal;
function sync(source: PatternInternal | PatternInternal[], options: OptionsInternal & EntryObjectPredicate): EntryInternal[];
function sync(source: PatternInternal | PatternInternal[], options?: OptionsInternal): string[];
function stream(source: PatternInternal | PatternInternal[], options?: OptionsInternal): NodeJS.ReadableStream;
function generateTasks(source: PatternInternal | PatternInternal[], options?: OptionsInternal): Task[];
function isDynamicPattern(source: PatternInternal, options?: OptionsInternal): boolean;
function escapePath(source: PatternInternal): PatternInternal;
}
export = FastGlob;
我试过使用以下测试的变体,但 TS 抱怨它只能在命名空间(同步、流等)中找到函数。删除函数的字符串名称会导致不同的问题。
import * as FastGlob from 'fast-glob';
import { stub, SinonStub } from "sinon";
import { Pattern, Entry, Options } from "fast-glob";
(stub(FastGlob, "FastGlob") as unknown as SinonStub<[s: Pattern | Pattern[], o: Options], Promise<Entry[]>>).resolves([{test: '/test/'} as unknown as Entry])
应用程序代码是这样使用的
import * as glob from 'fast-glob';
const paths: Array<string> = await glob('./my/glob/**/*.ts', { absolute: true });
你需要额外的模块来存根 fast-glob,因为它定义的方式。欲了解更多信息,您可以查看此 sinon issue.
如果你可以使用额外的模块,我可以给你举个例子:proxyquire.
我有这个glob.ts。
// File: glob.ts
import glob from 'fast-glob';
async function getPaths(input: string): Promise<Array<glob.Entry|string>> {
return glob(input, { absolute: true });
}
export { getPaths };
使用规范文件进行测试:
// File: glob.spec.ts
import * as FastGlob from 'fast-glob';
import sinon from 'sinon';
import proxyquire from 'proxyquire';
import { expect } from 'chai';
describe('Glob', () => {
const fakeInput = './node_modules/**/settings.js';
it('getPaths using first fast-glob definition', async () => {
const fakeResult = [{ test: '/test/' } as unknown as FastGlob.Entry];
const fakeFunc = sinon.fake.resolves(fakeResult);
// Create stub using proxyquire.
const glob = proxyquire('./glob', {
'fast-glob': sinon.fake.resolves(fakeResult),
});
const paths = await glob.getPaths(fakeInput);
expect(paths).to.deep.equal(fakeResult);
expect(fakeFunc.calledOnceWithExactly(fakeInput));
})
it('getPaths using second fast-glob definition', async () => {
const fakeResult = ['/test/'];
const fakeFunc = sinon.fake.resolves(fakeResult);
// Create stub using proxyquire.
const glob = proxyquire('./glob', {
'fast-glob': sinon.fake.resolves(fakeResult),
});
const paths = await glob.getPaths(fakeInput);
expect(paths).to.deep.equal(fakeResult);
expect(fakeFunc.calledOnceWithExactly(fakeInput));
})
});
当你运行它从终端使用 ts-mocha 和 nyc 时:
$ npx nyc ts-mocha glob.spec.ts
Glob
✔ getPaths using first fast-glob definition (137ms)
✔ getPaths using second fast-glob definition
2 passing (148ms)
--------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
--------------|---------|----------|---------|---------|-------------------
All files | 100 | 100 | 100 | 100 |
glob.spec.ts | 100 | 100 | 100 | 100 |
glob.ts | 100 | 100 | 100 | 100 |
--------------|---------|----------|---------|---------|-------------------