如何对调用其他成员函数(C#或Java)的函数进行单元测试?

时间:2014-08-14 01:04:38

标签: unit-testing

假设我有一个如下课程,我想对单元测试' DoCalculate(arg1,arg2)'功能:

public class Calc
{
    public int DoCalculate(int arg1, int arg2)
    {
         int num1 = this.GetNum1(); // member function
         int num2 = this.GetNum2(); // member function

         if( this.flag1)  // member variable
         {
             return num1*num2+arg1-arg2;
         }
         else 
         {
             int num3 = this.GetNum3();  // member function
             return num3 + arg2;
         }
    }
}

在此函数中,它从其他成员函数和成员变量中获取输入。

如何对此功能进行单元测试? 或者如何重构以使其可单元测试?

2 个答案:

答案 0 :(得分:5)

我认为这里有几个选择。

解决方案可能取决于您的函数GetNum*()实际执行的操作。

当单元测试是两件事之一时,你想要什么,

  • 测试给定特定状态和指定输入,然后状态按预期方式变化和/或返回预期结果。
  • 以预期的方式测试组件之间的交互

看起来你的测试是第一种类型。因此,为了使您的测试有用,您需要让您的类进入已知状态,以便GetNum*()函数(和您的标志)在调用时返回预期值。

  • 是否可以创建类的实例,以便在调用函数GetNum*()时知道它们将返回什么(即可以通过设置属性或调用类的其他方法来完成)
  • GetNum*()函数执行非确定性操作(例如调用Web服务或从数据库加载某些内容)。

如果您处于第一种情况,那么很好,只需调用必要的方法/属性来创建您需要的状态,然后调用您的函数并断言结果。

如果您处于第二种情况,那么您需要考虑将您的类分开,并将执行外部调用的位转换为一个单独的类(实现定义两个类之间的契约的接口)有一个依赖。然后,您可以通过其构造函数将新接口的实例传递到此类(或者可能传入您正在调用的方法,但可能是构造函数),然后在测试中传递一个模拟,该模拟提供您需要能够测试的值。方法快速可靠。

答案 1 :(得分:2)

您可以将其作为任何其他公共方法进行测试 - 通过指定输入参数和预期结果。它调用其他成员的事实是无关的实现细节

为什么呢?给你一个想法 - 想想如果用这些方法体替换成员方法调用会发生什么变化。从单元测试的角度来看 - 没什么。

现在,调用的其他方法可能相当复杂,很难确定输入输出值。如果是这种情况,我建议给这个类另一个看 - 也许它是doing too many things at once,它的某些部分应该存在于其他类中。