java - 单元测试、静态和工厂

标签 java unit-testing junit static-methods

我正在用 Java 实现一个模型,它需要迭代一个集合并经历多个识别阶段,它涉及 for 循环、while 循环等。这是我想在细粒度级别测试的东西这样我就有信心它已得到正确实现。

我将它作为开始单元测试的机会,因为我认为这对我的代码有益。从那以后,我一直在阅读大量书籍,以跟上 JUnit 和单元测试的速度。

基本上我的问题归结为我收到的两条相互矛盾的建议:

1) 静电是邪恶的。请勿触摸静电。也不要测试 privates,你可能想要一个类。
2) 使用工厂进行创建以允许使用参数进行依赖注入(inject)——可能允许使用模拟和 stub 进行隔离。

在我的示例中,我希望按照以下方式执行操作:

double height = 223.42; // this was set iterating over a collection of doubles
//blah
HeightBounds b = HeightBounds.getHeightBounds(height);
//more blah

我这样做是为了避免建立一个非常长和复杂的代码块,我只能对其进行整体测试。这样我就有了可以测试的公共(public)可访问对象,以确保系统组件都能正确运行。

常识告诉我静态工厂没有任何问题,而且它们很容易测试,但考虑到我正在学习测试驱动设计,我是否遗漏了一些非常明显的东西?

谢谢

最佳答案

静态工厂类在您的类和HeightBounds 类之间引入耦合。这可能会使您的类难以测试,例如,如果 HeightBounds 关闭并在数据库中查找信息,或从 Web 服务读取等等。

如果您改为将 IHeightBounds 实现注入(inject)到您的类中,那么您可以模拟它,以便您可以测试当您的类的依赖项执行某些操作时会发生什么。

例如,如果 HeightBounds 抛出异常怎么办?或返回空?或者您想测试何时返回特定的 HeightBound?使用接口(interface)很容易模拟这种行为,使用静态工厂则更难,因为您已经制造了数据以在类中创建所需的结果。

您仍然可以只有一个 HeightBounds 的实现,并且能够单独测试它,但是您甚至可以在没有真正的实现的情况下测试上面的方法。

我可能会有一个 IHeightBoundFactory 接口(interface)并将一个实现注入(inject)到类中。

至于测试私有(private),通常你不想。您想要测试两件事中的一件,或者结果是您所期望的,或者交互是您所期望的。

如果您有一个名为 Add 的方法和一个名为 GetAll 的方法,那么您可能想在调用 Add 时测试它,然后调用GetAll 你会取回你添加的那个。您不关心它是如何实现的,只关心它的工作原理。这是测试结果。通常在这种情况下,您希望创建返回数据的模拟对象。这似乎是你的情况。

如果当您调用 Add 时您希望记录添加的内容,那么您想要测试与日志记录依赖项的交互,因此您注入(inject)一个模拟依赖项并验证与它的交互当您调用 Add 时发生类。通常在这种情况下,您希望创建具有预期设置的模拟对象,并验证是否已满足这些预期。在您上述情况下,这看起来没有必要。

关于java - 单元测试、静态和工厂,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5637495/

相关文章:

java - JSoup 是否找到所有图像

java - 将监听器注册到从数组创建的 JButton 的最佳位置在哪里?

java - 为什么 junit 中的 assertEquals 和 assertSame 为同一类的两个实例返回相同的结果?

java - Mockito/PowerMock 兼容性问题

java - 如何测试使用外部包与数据库交互的方法

java - 在事先未知的 SerializedName 上使用 Gson/Retrofit

python - Django 应用程序中的单元测试 Elasticsearch

c# - 如何将强制转换接口(interface)类型化为具体类型

c# - 如何在 ASP.NET Core 中测试 https 重定向?

testing - Ant 测试编译崩溃