unit-testing - 如何在不重构为单独的类的情况下对私有(private)代码进行单元测试?

标签 unit-testing language-agnostic oop

假设我有一个执行一些计算的私有(private)例程:

private function TCar.Speed: float
{
   Result = m_furlogs * 23;
}

但现在我想开始更彻底地测试这个计算,所以我将它重构为一个单独的函数:
public function TCar.Speed: float
{
   Result = CalculateSpeed(m_furlogs);
}

private function TCar.CalculateSpeed(single furlogs): float 
{
   Result = furlogs * 23;
}

现在我可以对 CalculateSpeed 进行各种测试:
Check( CalculateSpeed(0)  =  0);
Check( CalculateSpeed(1)  = 23);
Check( CalculateSpeed(2)  = 46);
Check( CalculateSpeed(88) = -1);

除了我不能执行这些测试,因为 CalculateSpeedTCar 是私有(private)的.单元测试的一个抽象概念是你从不测试私有(private)代码——只测试公共(public)接口(interface)。实际上,*x*Unit 的结构通常不能访问被测试的单独类的私有(private)方法。

问题是该类的其余部分都没有设置为处理单元测试。这是第一个进行任何类型测试的例程。并且很难为主机类配置一组初始条件,以便我测试调用 CalculateSpeed使用我想要的每一组输入。

我能看到的唯一选择是将这个私有(private)计算移到它自己的 TCarCalculateSpeed 中。类(class):
public class TCarCalculateSpeed
{  
   public function CalculateSpeed(float furlogs)
   {
      Result = furlogs * 23;
   }
}

整个类(class),致力于公开一种方法,应该是私有(private)的,只是为了让我可以测试它?

类(class)爆炸。

再加上它是私有(private)的。如果我想让它公开,我宁愿将它推广到 公众 可见性 - 至少这样我保存了一个正在创建的单独类。

我想添加一些单元测试;但随着代码的变化,它只能分小块完成。我不能完全重新设计运行 12 年的软件,可能会破坏一切,因为我想测试一个内部计算。

我目前最好的想法是添加一个 Test我的方法Car类,只需调用它:
TCar Car = new TCar();
Car.RunTests;

public procedure TCar.RunTests
{
   Check( CalculateSpeed(0)  =  0);
   Check( CalculateSpeed(1)  = 23);
   Check( CalculateSpeed(2)  = 46);
   Check( CalculateSpeed(88) = -1);
}

但现在我必须弄清楚如何拥有TCar.RunTests被外部 TestRunner 触发,仅设计为使用 TestCase类。

注:我已经尽了最大的努力来混合多种语言的语法。换句话说:语言不可知论。

最佳答案

这实际上与语言无关,因为保护机制和绕过它们的策略因语言而异。

但是大多数语言确实以某种形式提供了绕过,正如其他人所指出的,有时在私有(private)和公共(public)之间存在保护,使测试更容易。

例如,在 Java 中,如果您确实需要,可以将反射用于私有(private)内容,并且可以将内容设置为 protected 或包私有(private)的,这样您就不需要反射了。

一般来说,如果某些东西足够复杂以至于需要测试,则不应将其作为私有(private)方法或类埋在其他东西中。它正在做一些值得拥有自己的类(Class)的事情。

与其担心类的数量,不如担心它们的大小和复杂性。许多小类秉承Single Responsibility Principle比少数类在内部做复杂的事情要好。

关于unit-testing - 如何在不重构为单独的类的情况下对私有(private)代码进行单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3824961/

相关文章:

java - 维护 Junit 中测试的执行顺序

math - float 学有问题吗?

PHP 面向对象编程 : Unique ID property among all instances of class

javascript - Laravel-Vue 单元测试错误 "SyntaxError: Unexpected token {"

java - 使用 JUnit 测试图像文件

Python 单元测试哲学和排序

design-patterns - 原型(prototype)设计模式真的只是克隆吗?

multithreading - 如何识别一个擅长多线程编程的程序员?

python - 如何从Python中的不同文件夹导入类

c# - 与不同类型的接口(interface)