Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock abstract protected method

I have an abstract class:

public abstract class MyClass
{
    protected abstract bool IsSavable();

    protected bool IsExecutable()
    {
        //New mode or edit mode
        if (ViewMode == ViewMode.New || ViewMode == ViewMode.Edit)
        {
            return IsSavable();
        }

        //Search mode
        if (ViewMode == ViewMode.Search)
        {
            return true;
        }

        return false;
    }
}

I would like to unit test this class. Therefor I need to mock the "IsSavable" method. It should always return "true".

I know how to mock my abstract class with Moq. But how can I mock my abstract protected method so it returns true?

The function IsSavable is called in my abstract class by a concrete method (IsExecuteable). I would like to test this method. I know that most of you will recommend to test both in the class where "IsSavable" is implemented. Unfortunately this will be a lot of classes and I would like to test my method IsExecutable only once.

like image 537
mosquito87 Avatar asked Nov 27 '14 15:11

mosquito87


People also ask

What is protected abstract?

Abstract is a programming concept to create a pattern for other classes. protected is an access modifier like public and private. protected variables can be accessed from all classes in your package.

Can we spy abstract class?

It is now possible to conveniently spy on abstract classes. Note that overusing spies hints at code design smells (see spy(Object) ). Previously, spying was only possible on instances of objects. New API makes it possible to use constructor when creating an instance of the mock.


1 Answers

I would like to unit test this class. Therefor I need to mock the "IsSavable" method. It should always return "true".

No, that's a non-sequitur. You can just create a subclass which does what you want:

// Within your test code
class MyClassForTest : MyClass
{
    // TODO: Consider making this a property 
    protected override bool IsSavable()
    {
        return true;
    }
}

Then when you want to run a test, create an instance of MyClassForTest instead of just MyClass.

Personally I prefer to use mocking frameworks for dependencies rather than the classes I'm testing.

like image 189
Jon Skeet Avatar answered Sep 28 '22 11:09

Jon Skeet