问题
- 访问模块中所有JavaScript/TypeScript函数进行单元测试的正确/可接受的方式是什么
- 有没有一个(好的)理由让我不应该只导出我的所有函数
上下文
请原谅我的无知;我职业生涯的大部分时间都在使用测试驱动开发(TDD)方法编写Python代码。现在,我发现自己正在学习ReactJS/TypeScript,并弄清楚如何实现单元测试,但我很快发现,只有导出函数才能访问它们。正如你们大多数人所知,Python是非常宽容的;实际上没有隐私的概念,所以这只是导入模块并尊重您可以访问的内容的问题。但JavaScript只导入已明确导出的模块的功能,因此提供了一个适度的障碍。
有人告诉我,导出我的所有函数进行测试不是一个好主意,但我不知道有其他方法可以真正测试它们。
示例
有人告诉我;"正确/更好":
示例1.js:
const func1 = () => {
//code that does stuff
return "stuff";
};
const func2 = () => {
//code that does other stuff
return "otherStuff";
};
export { func1 };
Sample1.test.js:
// executed via Jest framework
import * as sample from "./Sample1.js"
describe("Unit Tests for Sample1", () => {
test("Unit Test - func1", () => {
// code that tests stuff
};
test("Unit Test - func2", () => {
// can't test func2 because it's not exported
};
};
我正在做的是能够测试所有功能:
示例2.js:
const func1 = () => {
//code that does stuff
return "stuff";
};
const func2 = () => {
//code that does other stuff
return "otherStuff";
};
export { func1, func2 };
Sample2.test.js:
// executed via Jest framework
import * as sample from "./Sample2.js"
describe("Unit Tests for Sample2", () => {
test("Unit Test - func1", () => {
// code that tests stuff
};
test("Unit Test - func2", () => {
// code that tests other stuff because it's exported
};
};
记录在案
我在互联网和Stack Overflow上专门查找了标准和最佳实践,但我没有发现太多能回答这个特定问题的内容。我发现的最接近的问题是这个SO问题,但这并不是我真正想要的。
如果您在测试系统(SUT)之前编写测试,从而真正进行测试驱动开发(TDD),那么您可以将测试视为SUT的可执行规范。(如果这对你来说已经很明显了,我很抱歉,但Stack Overflow上的许多人将TDD一词与单元测试互换使用,并说他们做TDD,即使他们在SUT之后写测试。)
因此,测试描述了SUT的API。在具有访问修饰符和/或显式导出功能的语言中,您需要使SUT可用于测试。在JavaScript中,这意味着您必须导出要测试的API。在其他带有访问修饰符的语言中,这也意味着必须提供SUT APIpublic
可用性(例如Java和C#)。
如果您正在开发一个库,这也将与客户端代码可用的API相一致。事实上,测试是SUT的第一个(或最早的)客户端。
一旦测试到位,它们就充当SUT的回归测试套件。因此,如果测试失败,则表明导出的API的某些部分已损坏。这也意味着该部分将被使用它的客户端代码破坏
那么,是否应该导出所有方法?
不一定。您可能希望将某些方法隐藏为实现详细信息。这可能有多种充分的理由。也许您不确定助手方法的API是否健壮,并且您希望保留在不破坏客户端代码的情况下更改它的能力。也许helper方法的封装性较差。
只要在TDD过程中创建了这样的辅助方法,即使它们本身没有导出,它们仍然会被测试过渡性地覆盖。