How to Unit Test an Abstract Class
--
How to unit test an abstract class? Or a whole class hierarchy that depends on that abstract class? Let’s see.
Unit testing an abstract class
Imagine you work on a people software in a university and have the following code:
public class Student
{
public string Name { get; set; } public void EnrollInCourse(Course course)
{
/* ... */
} public string GetSignature()
{
return $"Best regards,\r\n{Name},\r\nStudent at MIT";
}
}public class Professor
{
public string Name { get; set; } public void ApplyForFacultyJob(Faculty faculty)
{
/* ... */
} public string GetSignature()
{
return $"Best regards,\r\n{Name},\r\nProfessor at MIT";
}
}
In this example, Student
and Professor
share common functionality, and so you decide to extract it into a Person
abstract base class:
public class Student : Person
{
public void EnrollInCourse(Course course)
{
/* ... */
} protected override string GetTitle() => "Student";
}public class Professor : Person
{
public void ApplyForFacultyJob(Faculty faculty)
{
/* ... */
} protected override string GetTitle() => "Professor";
}public abstract class Person
{
public string Name { get; set; } protected abstract string GetTitle(); public string GetSignature()
{
return $"Best regards,\r\n{Name},\r\n{GetTitle()} at MIT";
}
}
This version looks much better because it follows the DRY principle.
Now, the question is — how to test it?
There are two options:
- Unit test all classes — When you test each class separately (
Student
,Professor
, andPerson
) - Unit test only concrete classes — When you test only the non-abstract classes (
Student
andProfessor
)
Let’s discuss them separately.
Test class per each production class
Testing each class in the hierarchy provides the benefit of not repeating your tests. Both Student
and Professor
derive the…