45

Used the create unit tests tool in Visual Studio and obviously it tries to instantiate my abstract classes.

My question is: Should I try to unit test the way Visual Studio is trying to get me to do it, or should I create a mock class to be instantiated, or should I only test the methods that use this abstract class?

Thanks.

ediblecode
  • 11,701
  • 19
  • 68
  • 116

5 Answers5

86

If there are methods on this abstract class that are worth testing, then you should test them. You could always subclass the abstract class for the test (and name it like MyAbstractClassTesting) and test this new concrete class.

sloth
  • 99,095
  • 21
  • 171
  • 219
34

There are two opposite points of view:

  • Do not test abstract class itself, test concrete classes inherited from it
  • Abstract class should be tested as well because provides some built in logic shared across all the inherited classes so you just test base logic in abstract class once

I prefer second option (currently) and testing abstract classes using RhinoMocks PartialMock feature which allows me to create a mock of an abstract class.

sll
  • 61,540
  • 22
  • 104
  • 156
8
  1. Just test the implementing classes.

  2. You could always create a specific implementation for testing that adds no extra functionality.

  3. Listen to the tests. Using mocking tools that do magic to allow testing abstract classes and private methods etc. are a test code smell

blank
  • 17,852
  • 20
  • 105
  • 159
0

use from mockrepository :

[testmethod]
       public void testwithmockrepository()
       {
           var mockrepository = new rhino.mocks.mockrepository();
           var mock = mockrepository.partialmock<myabstractclass>();

           using ( mockrepository.record() )
           {
               expect.call( mock.dosomething( arg<string>.is.anything ) ).return( "hi..." ).repeat.once();
           }
           using ( mockrepository.playback() )
           {
               assert.areequal( "hi..." , mock.dosomething( "salam" ) );
           }
       }
Mohammad Almasi
  • 400
  • 6
  • 19
-1

I would not test the abstract classes because of a very simple reason: the implementing class may have their own implementation of certain methods - if you test the abstract class, you wont have idea how the further code actually behaves. Moreover, if you test abstract classe's implemented methods, then you are binding your test with the abstract class implementation - but you can't create object of abstract class so what is the use of such test? :)

Eru
  • 332
  • 3
  • 17
  • All code that is written should have tests, regardless of whether it is used or not. If you have implementations that overwrite some abstract implementations you have to test those as well and not skip the abstract implementation. – Darkproduct May 25 '21 at 11:50
  • If an abstract class implements any method then this method should be tested. It's not that hard to understand. An abstract class can have method implementations that can be overwritten by class implementations. This means, that you have to make sure to test the original implementation from the abstract class as well. – Darkproduct May 27 '21 at 13:57
  • That is the point that you don't have to test this within the abstract class! You have derived from abstract class, you did NOT overwrite that implemented method and you test this within the tests for your derived class, the result will be correct. But you are testing the derived class not the abstract. But I suppose that you can have many different approaches and trying to find the "golden egg" is like discussing what is better: C# or Java :) – Eru May 28 '21 at 08:54