How to unit test a function that calls other member functions (C # or Java)?

Let's say I have a class like below and I want to unit test the DoCalculate (arg1, arg2) function:

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

      

In this function, it receives input from other member functions and member variables.

How to unit test this function? Or how do you refactor to make it a single testable?

+3


source to share


2 answers


I think there are a couple of options here.

The decision probably depends on what your functions actually do GetNum*()

.

What do you want when unit testing is one of two things,

  • to check that given state and given inputs, the state is returned in the expected manner and / or the expected results.
  • To test interoperability between components, the expected path goes


it looks like your tests are of the first type. So for your test to be useful, you need your class to be in a known state so that functions GetNum*()

(and your flags) return the expected values ​​when they are called.

  • Is it possible to instantiate your class so that when you call functions GetNum*()

    you know what they will return (i.e. this can be done by setting properties or calling other class methods)
  • or do is GetNum*()

    doing something non-deterministic (like calling a web service or loading something from a database).

if you are in the first situation then great, just call the required methods / properties to create the state you want, then call your function and assert the results.

If you are in the second situation, you need to think about splitting your class and making the bit that does external calls into a separate class (which implements the interface that defines the contract between the two classes) on which that class has a dependency. Then you can pass an instance of your new interface to that class through your constructor (or maybe to the method you are calling, but probably the constructor) and then in your tests pass a mock that provides the values ​​the method needs to test fast and reliable.

+5


source


You test it like any other public method - by specifying the input arguments and the expected result. The fact that it calls other members is an irrelevant implementation detail .

Why? To give you an idea - think about what would change if you replaced the member methods of a method with these method bodies. From a unit test point of view, nothing.



Now there is a possibility that the other methods called are quite complex and it will be difficult to determine the I / O values. If so, I would suggest giving this class a different perspective - perhaps doing too many things at once , and some parts of it should live in other classes.

+2


source







All Articles