Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I unit test overloaded functions?

So I have a class that looks something like the following:

public class MyClass
{

    DatabaseDependency _depend;

    public MyClass(DatabaseDependency depend)
    {
        _depend = depend;
    }

    public string DoSomething(DBParameter database)
    {
        var result = _depend.GetResults(database, ...);
        string response = String.Empty;        

        // some logic to process the result 

        return response;
    }

}

Where DBParameter is a simple value class which contains properties like Server, DBName, DBType, etc.

Now, I want to add an overload to DoSomething so that it accepts a connection string instead of the DBParameter parameter (assume that DatabaseDependency already has a GetResults overload which accepts a connection string).

My question: I have several unit tests which describe the various logical paths used to process result from DatabaseDependency.GetResults. When I add the overload to DoSomething, I would essentially refactor the code so that this logic is reused by both overloads (i.e. probably move it to a private method). What is the right way to go about unit testing this? Do I need to have just as many unit tests to verify all logical paths for the new overload I am adding?

like image 945
jpoh Avatar asked Sep 15 '09 08:09

jpoh


People also ask

Should you write unit tests for every function?

The answer to the more general question is yes, you should unit test everything you can. Doing so creates a legacy for later so changes down the road can be done with peace of mind. It ensures that your code works as expected.

How do you unit test a function?

A typical unit test contains 3 phases: First, it initializes a small piece of an application it wants to test (also known as the system under test, or SUT), then it applies some stimulus to the system under test (usually by calling a method on it), and finally, it observes the resulting behavior.

How do you run a unit test case?

To run all the tests in a default group, choose the Run icon and then choose the group on the menu. Select the individual tests that you want to run, open the right-click menu for a selected test and then choose Run Selected Tests (or press Ctrl + R, T).


2 Answers

If your code stays the way it currently looks, then yes: you will need to unit test that method as well, essentially duplicating your test effort.

However, if it makes sense to implement the functionality so that one method simply calls the other, you could make that other method virtual. That would allow you to create a test-specific subclass where you simply verify that the virtual method is being invoked by the other method with the correct values.

Once that is verified by one or more unit tests, you don't need to test that method any further, because now you have proven that the method calls the other method correctly, and you can concentrate your testing efforts on that method.

like image 143
Mark Seemann Avatar answered Oct 04 '22 10:10

Mark Seemann


If you're confident that your overloaded method taking a string just converts to a connection object and then delegates to the original, you should add one more test method.

However this breaks down if you refactor the underlying overloaded methods such that no delegation takes place. In this scenario I'd feel more confident replicating all the tests for both methods.

I think the first route is the most pragmatic. However it's a good idea to run code coverage analysis once in a while, and that will indicate at a later time if more tests are required.

like image 29
Brian Agnew Avatar answered Oct 04 '22 10:10

Brian Agnew