Zach
Zach

Reputation: 5885

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

Say I have a class as 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 gets input from other member functions and member variables.

How to unit test this function? Or how to refactor to make it unit testable?

Upvotes: 3

Views: 1855

Answers (2)

k.m
k.m

Reputation: 31444

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

Why? To give you an idea - think about what would change if you replaced member method invocations with those method bodies. From unit test point of view - nothing.

Now, there is a possibility that other methods that are called are fairly complex and it will be difficult to determine input-output values. If this is the case, I'd suggest giving this class another look - perhaps it's doing too many things at once and some parts of it should live in other classes.

Upvotes: 2

Sam Holder
Sam Holder

Reputation: 32936

I think there are a couple of options here.

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

What you want when unit testing is one of 2 things,

  • to test that given a particular state and specified inputs then the state changes in the expected way and/or expected results are returned.
  • To test the interactions between components happens in the expected way

it looks like your tests is of the first type. So in order for your test to be useful you need to get your class into a known state such that GetNum*() functions (and your flags) return the expected values when they are called.

  • Is it possible to create an instance of your class such that when the functions GetNum*() are called you know what they are going to return (ie can this be done by setting properties or calling other methods of the class)
  • or do GetNum*() functions do something non-deterministic (like call a web service or load something from a database).

if you are in the first situation, then great, simply call the neccessary methods/properties to create the state you need, then call your function and assert the results.

If you are in the second situation then you need to think about breaking your class apart and making the bit that does the external calls into a separate class (which implements an interface defining the contract between the two classes) on which this class has a dependency. You can then pass an instance of your new interface into this class through its constructor (or maybe into the method you are calling, but probably constructor) and then in your tests pass a mock which provides the values you need to be able to test the method quickly and reliably.

Upvotes: 5

Related Questions