Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

unit-testing abstract classes and protected methods inside them

how can I test abstract classes and protected methods inside them? I know some of you will suggest that I shouldn't test the abstract class, but rather test the classes that derive from it instead. Thing is, I don't want to do that. I want to strictly test the abstract class itself. Here is the sample class:

public interface IF_SystemMessageHandler
{
    ...
}

public interface IF_SystemMessageSender
{
    ...
}

    public abstract class Component : IF_SystemMessageSender
    {

        private eVtCompId mComponentId;
        private eLayer mLayerId;
        private IF_SystemMessageHandler mLogger;

        protected Component(eVtCompId inComponentId, eLayer inLayerId, IF_SystemMessageHandler inMessageHandler)
        {
            mLayerId = inLayerId;
            mComponentId = inComponentId;
            mLogger = inMessageHandler;
        }

        protected void SendSystemMessage(ref eSystemMsgLevel inSystemMsgLevel, ref string inSysMsg)
        {
            mLogger.SendSystemMessage(...);
        }

        protected void SendSystemMessage(ref eSystemMsgLevel inSystemMsgLevel, ref eTextId inSysMsgID)
        {
            mLogger.SendSystemMessage(...);
        }

        public void SetMessageHandler(ref IF_SystemMessageHandler InSystemMessageHandler)
        {
            mLogger = InSystemMessageHandler;
        }

    }

I'm writing a unit test for it. I know that one of the things I can do is utilize a unit-testing framework (I have Moq), but I have no idea on how to use it for this particular instance.

like image 423
Anthony Avatar asked Dec 17 '12 04:12

Anthony


2 Answers

You need to use a 'testable' class that inherits from your class under test. For example, if you have a class like this:

public class ProtectedStuff
{
    protected bool MyProtectedMethod()
    {
        return true;
    }
}

Then in your unit test assembly, inherit from your class like this:

public class TestableProtectedStuff : ProtectedStuff
{
    public new bool MyProtectedMethod()
    {
        return base.MyProtectedMethod();
    } 
}

This gives you a class with exactly the same interface as the original, but now you can access the protected methods.

like image 132
Tim Long Avatar answered Oct 18 '22 20:10

Tim Long


In order for you to test your abstract class you need to instantiate it. So create a class for testing purposes that inherits from your Component (abstract) class.

Aside from the interfaces being used I don't see much to Mock.

like image 43
Ulises Avatar answered Oct 18 '22 22:10

Ulises