function shouldntBeExportedFn(){
// Does stuff that needs to be tested
// but is not for use outside of this package
}
export function exportedFn(){
// A function that should be called
// from code outside of this package and
// uses other functions in this package
}
export const exportedForTesting = {
shouldntBeExportedFn
}
在某种程度上,我不得不接受这样一个事实:如果我想要覆盖未导出/私有函数/方法的粒度单元测试,我真的应该公开它们。有些人会说这违反了封装,但也有人不同意。前一组人还会说,在函数被导出/公开之前,它本质上是一个实现细节,因此不应该进行单元测试。 如果你正在练习TDD,那么Mark Seeman's explanation should be relevant(Pluralsight),希望它能澄清为什么可以暴露东西。 我不知道您是否可以找到一些技巧,直接从您的单元测试中调用未导出的函数,而不对测试中的代码进行更改,但我个人不会这样做。
// existing private function, no change here
function function1(s :string) :boolean => {
let result=false; /* code, result=true if good */ return result;
}
// at bottom add this new code
// exports for testing only
// make the value something that will never be in production
if (process.env['NODE_DEV'] == 'TEST') {
module.exports.function1 = function1;
module.exports.function2 = function2; // add functions as needed
}
function privateFunction1() {/**/};
function privateFunction2() {/**/};
// Different syntax is a good visual indicator that this is different to public function
exports.privateFunction1 = privateFunction1;
exports.privateFunction2 = privateFunction2;
exports.publicFunction1 = function() {/**/};
exports.publicFunction2 = function() {/**/};
6条答案
按热度按时间c9x0cxw01#
导出“exportedForTesting”常量
以下代码可用于生产代码:
这可以用在单元测试中:
这个策略为我的团队中的其他开发人员保留了上下文线索,即除了测试之外,不应该在包之外使用
shouldntBeExportedFn()
。我已经用了很多年了,我发现它非常有效。
am46iovg2#
我希望我能给你一个更好的答案,乔丹。😊过去我在JavaScript和C#上下文中都有过非常相似的问题...
回答/不回答
在某种程度上,我不得不接受这样一个事实:如果我想要覆盖未导出/私有函数/方法的粒度单元测试,我真的应该公开它们。有些人会说这违反了封装,但也有人不同意。前一组人还会说,在函数被导出/公开之前,它本质上是一个实现细节,因此不应该进行单元测试。
如果你正在练习TDD,那么Mark Seeman's explanation should be relevant(Pluralsight),希望它能澄清为什么可以暴露东西。
我不知道您是否可以找到一些技巧,直接从您的单元测试中调用未导出的函数,而不对测试中的代码进行更改,但我个人不会这样做。
只是一个选择
另一种选择是将库一分为二,比如,库
A
是应用程序代码,库B
是包含所有那些您希望避免从A
的接口导出的函数的包。如果它们是两个不同的库,你可以在一个非常精细的级别上控制暴露的内容和测试的方式。库
A
将仅仅依赖于B
,而不会泄露B
的任何细节。A
和B
都可以独立测试。当然,这需要不同的代码组织,但它可以工作。Lerna等工具简化了JavaScript代码的多包存储库。
旁注
老实说,我不同意AlexSzabó的观点,通过测试使用非导出函数的函数来测试非导出函数并不是真正的单元测试。
jyztefdp3#
我知道这个问题已经有了答案,但我不喜欢选择的答案,因为它涉及到额外的功能。:)经过一些研究,导致我https://www.jstopics.com/articles/javascript-include-file(所以基本的想法可以在那里找到,并归功于他/她)。我的代码是Typescript,但这应该工作正常的Javascript了。
假设您的源应用位于“app.ts”中,并且您有一个名为“function 1”的私有函数:
我使用Jest来做单元测试,所以在tests/app.test.ts中我们做:
添加任何你需要的测试,它都会测试那些私有函数。它对我很有效,不需要重新布线。
guz6ccqo4#
也许是necro-posting,但是我解决这个问题的方法是使用一个“index.js”,它只导出你想公开的函数。
您仍然需要导出私有函数,但是这种方法确实在测试和生产之间增加了一个抽象层。
您甚至可以使用NODE_ENV变量来只导出不在生产环境中的私有函数。
42fyovps5#
如何测试快速路由中的专用功能
在我的例子中,我想为快速路由中的私有函数编写单元测试。
问题所在
如果我们这样做,测试工作正常:
不过,快递对此抱怨道:
TypeError app.use() requires a middleware function
......因为它希望看到的只是:
解决方案
我们需要将map添加为
router
上的属性:然后我们可以访问测试中的私有函数,就像Jordan的答案一样。
myss37ts6#
要测试私有函数,您可以在同一个文件中进行内联测试。测试部分将在绑定过程中移除。一些测试框架(如Vitest)允许这样做。