如何对非导出功能进行单元测试?

时间:2019-01-09 18:13:22

标签: javascript ecmascript-6 jestjs es6-modules

在Javascript es6-模块中,可能有许多应该测试但不应该导出的小型易测试功能。 如何在不导出功能的情况下测试模块中的功能?(不使用rewire

2 个答案:

答案 0 :(得分:2)

我希望乔丹能为您提供更好的答案。过去我在JS和C#上下文中都有非常相似的问题...

回答,不回答

在某些时候,我不得不接受这样一个事实:如果我想要涵盖未导出/私有函数/方法的细粒度单元测试,我真的应该公开它们。有人会说这是对封装的违反,但其他人则不同意。前一群人还会说,在导出/公开功能之前,它本质上是实现细节,因此不应进行单元测试。

如果您正在练习TDD,请Mark Seeman's explanation should be relevant(PluralSight)并希望阐明为什么可以公开这些内容。

我不知道您是否可以找到一些技巧,直接从单元测试中调用未导出的函数,而无需更改被测代码,但是我个人不会这样做。

只是一个选择

另一个选择是将您的库分成两个。例如,库A是您的应用程序代码,而库B是包含所有您要避免从A界面导出的功能的软件包。

如果它们是两个不同的库,则可以非常精细地控制公开的内容和测试方式。库A仅依赖于B,而不会泄漏B的任何详细信息。然后AB都可以独立测试。

当然,这将需要不同的代码组织,但是它将起作用。 Lerna之类的工具可简化JavaScript代码的多包存储库。

旁注

老实说,我不同意@AlexSzabó。通过测试使用它的功能来测试非导出功能并不是真正的单元测试。

答案 1 :(得分:1)

到目前为止,我已经提出了一些可能的选择,但是我正在寻找更好的建议。

导出“可测试对象”常量

function shouldntBeExported(){
    // Does stuff that needs to be tested
}
export function exported(){
    // Does stuff
    return shouldntBeExported();
}
export const testables = {
    shouldntBeExported:shouldntBeExported
}

这里的想法是我可以使用shouldntBeExported访问import {testables} from 'package';,并且保留了我团队中其他开发人员的上下文线索,即除测试外,不应在程序包之外使用它。

将“ shouldntBeExported()”设置为“ exported()”的属性

这个感觉很不对劲,但是却带来了一些独特的好处,尤其是如果该函数只能在一个“导出的”函数内部而不是在该程序包中的任何其他函数中调用时。 (当然,不是不可能从别人那里调用它,但是它使它在所属位置更加明显)。

export function exported(){
    // Does stuff
    return exported.shouldntBeExported();
}
exported.shouldntBeExported = function shouldntBeExported(){
    // Does stuff that needs to be tested
}