【发布时间】:2019-12-13 03:47:44
【问题描述】:
我正在将一组 Firebase 云函数从 Javascript 迁移到 Typescript。使用 JS,我能够使用 mocha、chai 和 sinon 进行单元测试,并存根各种数据库依赖项进行测试。对于 TS,我遇到了一些我不理解的问题和意外行为。
模式类似于:
mainFunction 调用helperFunction,后者调用nestedHelperFunction。
当我用一些测试数据调用mainFunction 时,我想在我的测试中存根或监视nestedHelperFunction。
mainFunction 位于 index.ts 中,helperFunction 和 nestedHelperFunction 位于 utils.ts 文件中。
奇怪行为的例子
// index.ts
import * as utils from './utils';
export async function mainFunction() {
console.log('Starting mainFunction...');
const promiseResults = await Promise.all([
Promise.resolve('One'),
utils.helperFunction(),
Promise.resolve('Three'),
]);
console.log(promiseResults);
return 1;
}
// utils.ts
export async function helperFunction() {
const newString = await nestedHelperFunction();
return 'helperFunction Result | ' + newString;
}
export async function nestedHelperFunction() {
return '***Nested***';
}
测试文件
//index.test.ts
import * as myFunctions from '../index';
import * as utils from '../utils';
import * as sinon from 'sinon';
import * as chai from 'chai';
const expect = chai.expect;
describe("Test Suite", () => {
let functionSpy: sinon.SinonStub;
beforeEach(() => {
functionSpy = sinon.stub(utils, 'helperFunction');
functionSpy.returns(Promise.resolve('Stubbed Function Results!'))
});
afterEach(() => {
functionSpy.restore();
});
it('should resolve and call the correct functions.', async () => {
const returnValue = await myFunctions.mainFunction();
expect(returnValue).to.equal(1);
expect(functionSpy.callCount).to.equal(1);
})
})
输出:
测试通过,我得到:[ 'One', 'Stubbed Function Results!', 'Three' ]
但是,如果我尝试对nestedHelperFunction 存根,它就不起作用。
// index.test.js
import * as myFunctions from '../index';
import * as utils from '../utils';
import * as sinon from 'sinon';
import * as chai from 'chai';
const expect = chai.expect;
describe("Test Suite", () => {
let functionSpy: sinon.SinonStub;
beforeEach(() => {
functionSpy = sinon.stub(utils, 'nestedHelperFunction'); // Changed
functionSpy.returns(Promise.resolve('Stubbed Function Results!'))
});
afterEach(() => {
functionSpy.restore();
});
it('should resolve and call the correct functions.', async () => {
const returnValue = await myFunctions.mainFunction();
expect(returnValue).to.equal(1);
expect(functionSpy.callCount).to.equal(1);
})
})
输出
测试失败,我得到未修改的输出:[ 'One', 'helperFunction Result | ***Nested***', 'Three' ]
为什么在存根 nestedHelperFunction 时它不起作用,但适用于 helperFunction?
工作示例
在utils.ts 内创建helperFunction 和nestedHelperFunction 作为类上的方法而不是“顶级”函数是可行的,但我不明白为什么。
// utils.ts
export class Utils {
static async helperFunction(): Promise<string> {
const newString = await this.nestedHelperFunction();
return 'helperFunction Result | ' + newString;
}
static async nestedHelperFunction (): Promise<string> {
return '***Nested Output***';
}
}
测试文件
// index.test.ts
import {mainFunction} from '../index';
import {Utils} from '../utils';
import sinon from 'sinon';
import * as chai from 'chai';
const expect = chai.expect;
describe("Test Suite", () => {
let functionSpy: sinon.SinonStub;
beforeEach(() => {
functionSpy = sinon.stub(Utils, 'nestedHelperFunction');
functionSpy.returns(Promise.resolve('Stubbed Function Results!'));
});
afterEach(() => {
functionSpy.restore();
});
it('should resolve and call the correct functions.', async () => {
const returnValue = await mainFunction();
expect(returnValue).to.equal(1);
expect(functionSpy.callCount).to.equal(1);
})
})
// index.ts
import {Utils} from './utils';
export async function mainFunction() {
console.log('Starting mainFunction...');
const promiseResults = await Promise.all([
Promise.resolve('One'),
Utils.helperFunction(),
Promise.resolve('Three'),
]);
console.log(promiseResults);
return 1;
}
输出
测试通过,我得到所需/预期的输出:[ 'One',
'helperFunction Result | Stubbed Function Results!',
'Three' ]
我读过的材料向我建议了导入 es6 模块或 Typescript 如何编译并可以更改导入项目的名称。在 Javascript 中,我使用 Rewire 来设置存根,其中一些是私有函数,但我在 Typescript 中遇到了问题。
感谢您的帮助。
【问题讨论】:
标签: typescript unit-testing sinon