views:

46

answers:

1

I'm trying to start using Unit Testing on my current project in Visual Studio 2010. My class structure, however, contains a number of interface and abstract class inheritance relationships.

If two classes are derived from the same abstract class, or interface I'd like to be able to share the testing code between them. I'm not sure how to do this exactly. I'm thinking I create a test class for each interface I want to test, but I'm not sure the correct way to feed my concrete classes into the applicable unit tests.


Update

OK here's an example. Say I have an interface IEmployee , which is implemented by an abstract class Employee, which is then inherited by the two concrete classes Worker and Employee. (Code show below)

Now say I want to create tests that apply to all IEmployees or Employees. Or alternatively create specific tests for specific types of Employees. For example I may want to assert that setting IEmployee.Number to a number less then zero for any implementation of IEmployee throws an exception. I'd prefer to write the tests from the perspective of any IEmployee and then be able to use the tests on any implementation of IEmployee.

Here's another example. I may also want to assert that setting the vacation time for any employee to a value less then zero throws and error. Yet I may also want to have different tests that apply to a specific concrete version of Employee. Say I want to test that Worker throws an exception if they are provided more then 14 days vacation, but a manager can be provided up to 36.

public interface IEmployee
{
    string Name {get; set;}
    int Number {get; set;}
}


public abstract class Employee:IEmploee
{
    string Name {get; set;}
    int Number {get;set;}
    public abstract int VacationTime(get; set;)
}


public abstract class Worker:IEmployee
{
    private int v;

    private int vTime;
    public abstract int VacationTime
    {
       get
       {
         return VTime;
       }
       set
      { 
         if(value>36) throw new ArgumentException("Exceeded allowed vaction");
         if(value<0)throw new ArgumentException("Vacation time must be >0");
         vTime= value;
       }
    }


    public void DoSomWork()
    {
      //Work
    }
}


public abstract class Manager:IEmployee
{
    public abstract int VacationTime
    {
       get
       {
         return VTime;
       }
       set
      { 
         if(value>14) throw new ArgumentException("Exceeded allowed vaction");
         if(value<0)throw new ArgumentException("Vacation time must be >0");
         vTime= value;
       }
    }

  public void DoSomeManaging()
  {
      //manage
  }

}

So I guess what I'm looking for is a work flow that will allow me to nest unit tests. So for example when I test the Manager class I want to first test that it passes the Employee and IEmployee tests, and then test specific members such as DoSomeManaging().

A: 

What I think you want to do is create unit tests for methods in abstract classes.

I'm not sure it makes sense to want to test a protected method on an abstract class, but if you insist simply extend the class in a class used exclusively for unittesting. That way you can expose the protected methods on the abstract class you want to test through public methods on the extending class that simply call through to the method on the abstract class.

If you have methods in abstract classes that you want unittested, I suggest refactoring them into separate classes and simply expose them as public methods and put those under test. Try looking at your inheritance tree from a 'test-first' perspective and I'm pretty sure you'll come up with that solution (or a similar one) as well.

JDT