Javascript 测试未导出的TypeScript函数

Javascript 测试未导出的TypeScript函数,javascript,typescript,mocha.js,chai,Javascript,Typescript,Mocha.js,Chai,我使用Mocha/Chai测试JavaScript前端代码,现在我们切换到TypeScript。我有几个功能要测试。但它们不应该是可出口的。我是否可以访问此函数并在不向其添加export的情况下对其进行测试 但它们不应该是可出口的。我是否可以在不向这些函数添加导出的情况下访问这些函数并对其进行测试 一般来说,不可以。可以访问私有类成员,但不能访问未报告的模块成员 我将回应@Katana314的评论——单元测试不应该使用非公共方法。尝试这样做表明您正在测试模块的实现细节,而不是模块声称要实现的契约

我使用Mocha/Chai测试JavaScript前端代码,现在我们切换到TypeScript。我有几个功能要测试。但它们不应该是可出口的。我是否可以访问此函数并在不向其添加
export
的情况下对其进行测试

但它们不应该是可出口的。我是否可以在不向这些函数添加导出的情况下访问这些函数并对其进行测试

一般来说,不可以。可以访问私有类成员,但不能访问未报告的模块成员


我将回应@Katana314的评论——单元测试不应该使用非公共方法。尝试这样做表明您正在测试模块的实现细节,而不是模块声称要实现的契约。

正如您在相关问题中所看到的,在类或模块内测试私有函数的问题在StackOverflow上引起了激烈的争论-以下可能是一个解决方案:甚至没有这样的讨论:

如果这些功能足够重要,可以单独测试,但不应该作为模块的一部分进行访问,那么它们是否应该放在自己的模块中


这将解决您的可访问性问题-它们现在是一个模块中的公共函数,您可以轻松地从另一个模块中使用它们,而不必将它们作为该模块的一部分公开。

这是一个彻底的攻击,但是

window.testing = {};
然后在您的模块中:

module.exports = {
    myPublicFunction: myPublicFunction
};

window.testing.myModule = {
    myPublicFunction: myPublicFunction,
    myPrivateFunction: myPrivateFunction
};

无法访问未导出的模块功能

module MyModule {
    function privateFunction() {
        alert("privateFunction");
    }
}
MyModule.privateFunction(); // Generates a compiler error
然而,撇开私有方法测试的有效性问题不谈,下面是您可以做的

将函数分组到实用程序类中,然后利用私有类成员可以通过方括号表示法访问这一事实

module MyModule {
    export class UtilityClass {
        private privateFunction() {
            alert("privateFunction");
        }   
    }
}
var utility = new MyModule.UtilityClass();
//utility.privateFunction(); Generates a compiler error
utility["privateFunction"](); // Alerts "privateFunction"

我找到的最佳解决方案是以不同的名称导出私有函数,这样这个名称会提醒您不要在其他任何地方使用这个函数

export const getPriceTEST = getPrice;

function getPrice(): number {
  return 10 + Math.Random() * 50;
}


虽然无法直接访问未导出的函数,但仍有一种方法可以以“半隐藏”的方式导出它们。一种可能的办法是:

// In your library module declare internal functions as non-exported like normal.
function someInternalFunctionA(x: number): number {
  return x;
}

function someInternalFunctionB(x: number): number {
  return x;
}

// At the bottom, offer a public escape hatch for accessing certain functions
// you would like to be available for testing.
export const _private = {
  someInternalFunctionA,
  someInternalFunctionB,
};
在测试端,您可以执行以下操作:

import { _private } from "./myModule";

test("someInternalFunctionA", () => {
  expect(_private.someInternalFunctionA(42)).toEqual(42);
});
我喜欢的方法是:

  • 无需直接用
    export
    标记
    someinternalfunction
  • 很明显,
    \u private
    下的内容并不是公共界面的正式部分

我认为这是一个普遍的编程观察;单元测试不应该关注私有方法。如果您有一些私有方法不在公共方法的某些用法中,那么就把它们去掉。如果它们被公共方法所覆盖,请使用这些公共方法。(过于简单的观点,但这就是想法)在切换到TypeScript之前,您如何处理这些问题?@Katana314我想对非导出函数进行一些基准测试。我该怎么做?这与测试哲学无关。@Katana314从我可以看出,这种观点有点过时。测试内部方法有完全有效的用例。多年来,我遇到了许多私有函数的例子,它们甚至允许进行比更高级别的公共接口更有意义的单元测试。单元测试的理想粒度并不总是与理想的公共接口一致。还要注意的是,现代语言(如Rust)通常采用甚至鼓励私人测试的设计。也请参见。因此,如果我想测试函数或用存根替换函数,我必须导出函数。我说得对吗?有人提出的论点是,你不应该仅仅为了测试而输出某些东西。您正在对模块进行单元测试,以确保传入一组值可以得到预期的结果,而不是模块内的内部处理流。