简体   繁体   English

测试未导出的 TypeScript 函数

[英]Testing TypeScript function which is not exported

I use Mocha/Chai for testing JavaScript front-end code and now we switched to TypeScript.我使用 Mocha/Chai 来测试 JavaScript 前端代码,现在我们切换到 TypeScript。 I have several functions I want to test.我有几个要测试的功能。 But they shouldn't be exportable.但它们不应该是可出口的。 Can I get an access to this functions and test it without adding export to them?我可以访问此功能并对其进行测试而不添加export吗?

There is no way to access a non-exported module function.无法访问非导出的模块函数。

module MyModule {
    function privateFunction() {
        alert("privateFunction");
    }
}
MyModule.privateFunction(); // Generates a compiler error

However, leaving aside the question of validity of private method testing, here is what you can do.但是,撇开私有​​方法测试的有效性问题不谈,您可以执行以下操作。

Group your functions into an utility class, and then leverage the fact that private class members can be accessed via square bracket notation.将您的函数分组到一个实用程序类中,然后利用可以通过方括号表示法访问私有类成员的事实。

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

While it is not possible to access non-exported function directly there is still a way to export them in a "semi-hidden" way.虽然无法直接访问非导出函数,但仍然可以通过“半隐藏”方式导出它们。 One possible approach would be:一种可能的方法是:

// 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,
};

On test side you can do:在测试方面,您可以执行以下操作:

import { _private } from "./myModule";

test("someInternalFunctionA", () => {
  expect(_private.someInternalFunctionA(42)).toEqual(42);
});

What I like about the approach:我喜欢这种方法的地方:

  • No need to mark someInternalFunctionA with export directly.不需要直接用export标记someInternalFunctionA
  • It should still be very obvious that the stuff under _private isn't officially part of the public interface. _private下的东西不是公共接口的正式组成部分,这应该仍然是非常明显的。

As you can see in related questions the issue of testing private functions inside classes or modules is heavily debated on StackOverflow - The following might be an architectural solution to not even have that discussion:正如您在相关问题中所看到的,在 StackOverflow 上对在类或模块中测试私有函数的问题进行了激烈的辩论 - 以下可能是一种架构解决方案,甚至没有进行这种讨论:

If these functions feel important enough to be tested separately, but should not be accessible as part of a module, should they maybe be placed in their own module?如果这些功能足够重要,可以单独测试,但不应作为模块的一部分访问,是否应该将它们放在自己的模块中?

This would solve your issue of accessibility - they now are public functions in one module, and you can easily use them from within another module and not expose them as part of that module.这将解决您的可访问性问题 - 它们现在是一个模块中的公共函数,您可以轻松地从另一个模块中使用它们,而不是将它们作为该模块的一部分公开。

Best solution I found is to export the private function under different name so this name will remind you not to use this function anywhere else.我发现的最佳解决方案是以不同的名称导出私有函数,因此该名称会提醒您不要在其他任何地方使用此函数。

export const getPriceTEST = getPrice;

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

But they shouldn't be exportable.但它们不应该是可出口的。 Can I get an access to this functions and test it without adding export to them?我可以访问此功能并对其进行测试而不添加导出吗?

In general, no.一般来说,没有。 It's possible to access private class members, but not unexported members of modules.可以访问私有类成员,但不能访问模块的未导出成员。

I would echo @Katana314's comments -- unit tests should not be concerning themselves with non-public methods.我会回应@Katana314 的评论——单元测试不应该与非公共方法有关。 Trying to do so is an indication that you're testing the implementation details of the module rather than the contract the module claims to implement.尝试这样做表明您正在测试模块的实现细节,而不是模块声称要实现的契约。

This is a total hack, but hey...这是一个彻头彻尾的黑客,但是嘿......

window.testing = {};

Then in your module:然后在你的模块中:

module.exports = {
    myPublicFunction: myPublicFunction
};

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM