24

I am trying to run a unit test on a method in an abstract class. I have condensed the code below:

Abstract Class:

public abstract class TestAb
{
    public void Print()
    {
        Console.WriteLine("method has been called");
    }
}

Test:

[Test]
void Test()
{
    var mock = new Mock<TestAb>();
    mock.CallBase = true;
    var ta = mock.Object;
    ta.Print();
    mock.Verify(m => m.Print());
}

Message:

Method is not public

What am I doing wrong here? My goal is to test the methods inside the abstract class using he Moq framework.

Guerrilla
  • 13,375
  • 31
  • 109
  • 210
  • Did you see this thread? http://stackoverflow.com/questions/3604721/how-to-test-a-method-in-an-abstract-class-with-abstract-methods – Dilish Dec 15 '13 at 06:42

3 Answers3

23

The message is because your Test() method is not public. Test methods need to be public. Even after making the test method public it will fail as you can only verify abstract/virtual methods. So in your case you will have to make the method virtual since you have implementation.

Yousha Aleayoub
  • 4,532
  • 4
  • 53
  • 64
Adarsh Shah
  • 6,755
  • 2
  • 25
  • 39
6

If you want to mock methods on an abstract class like this, then you need to make it either virtual, or abstract.

Adam Rackis
  • 82,527
  • 56
  • 270
  • 393
3

My answer for the similar question :

As a workaround you can use not the method itself but create virtual wrapper method instead

public abstract class TestAb
{
    protected virtual void PrintReal(){
            Console.WriteLine("method has been called");
    }

    public void Print()
    {
        PrintReal();
    }
}

And then override it in the test class:

abstract class TestAbDelegate: TestAb{

     public abstract override  bool PrintReal();
}

Test:

[Test]
void Test()
{
    var mock = new Mock<TestAbDelegate>();
    mock.CallBase = true;

   mock.Setup(db => db.PrintReal());

    var ta = mock.Object;
    ta.Print();

    mock.Verify(m => m.PrintReal());
}
Stadub Dima
  • 858
  • 10
  • 24