Mulitple Constraint Generics and Test Base Classes

This was basically an idea I had to have test classes inherit a TestBase that has a Static Create method on it. The reason for this is that I have found it easier to have a Create method that takes care of creating a temporary class of the type the test represents. Say I have a UserTest class and I need an address. Instead of creating and filling a whole address object in the UserTest, it easier to have a Create Method on the AddressTest class that gives me a premade Address object. Why would I want to redo a lot of the same code by having the create method on every class when I can have it on a base class and just have the non base classes specify how to create the object?

Is this really needed? I can’t argue absolutely, but this forces a Create method to appear on any test class that inherits from TestBase and by use of Exceptions, forces the child classes to define how to create the object they represent. (As in it forces AddressTest to define how to create an Address object.) This also allows the Create method to be static and inherited. You could make it abstract, to skip the need for the two create methods(Create and CreateInstance), but that would hose the whole situation since static abstract is a no no. Static is a must for this situation.

The idea behind the code is to have a static Create method on the TestBase class that when called will create the test class type passed in through generics.

public static I Create()
 {
     I returnValue;
     J testToUse;

     testToUse = System.Activator.CreateInstance<J>();
     returnValue = testToUse.CreateInstance();

     return returnValue;
 }

Where J is the test class type to create. Once that test class is instantiated, the virtual method CreateInstance is called. This is where the test class creates the instance of the object it represents.

protected override I CreateInstance()
{
     I returnValue;

     returnValue = (I)new SimpleItem();
     returnValue.IsSimple = true;
     return returnValue;
}

Where I is the type of object it is going to create. In use it will look something like this:

  ItemBase itemToCreate;

  itemToCreate = SimpleItemTest<SimpleItem>.Create();

Now for the code:

//Some junk base items to demostrate the creating of an item with a base class
public class ItemBase 
{
}

//One item that will be created
public class SimpleItem : ItemBase
{
 public Boolean IsSimple { get; set; }
}

//The other item that can be created.
public class ComplexItem : ItemBase
{
 public Boolean IsComplex { get; set; }
 public Boolean IsNotSimple { get; set; }
}

//This test will be used to create a SimpleItem
public class SimpleItemTest<I> : TestBase<I, SimpleItemTest<I>> where I : SimpleItem
{
 protected override I CreateInstance()
 {
     I returnValue;

     returnValue = (I)new SimpleItem();
     returnValue.IsSimple = true;
     return returnValue;
 }
}

//This test will be used to create a ComplexItem
public class ComplexItemTest<I> : TestBase<I, ComplexItemTest<I>> where I : ComplexItem
{
 protected override I CreateInstance()
 {
     I returnValue;

     returnValue = (I)new ComplexItem();
     returnValue.IsComplex = true;
     returnValue.IsNotSimple = true;
     return returnValue;
 }
}

//This is the base class where the Create Method resides
public class TestBase<I, j> where I : class where J : TestBase<I, j>
{
 //This will either be overridden or throw an error.  Kind of a forced
 //abstract.  This is the method that the child test classes will use to
 //create whatever class they represent.
 protected virtual I CreateInstance()
 {
     throw new System.NotImplementedException();
 }

 //This is used to create a test class and call the CreateInstance method
 //so that this method can return the correct object.  The object type is
 //dependent on the type of test class that is being created.
 public static I Create()
 {
     I returnValue;
     J testToUse;

     testToUse = System.Activator.CreateInstance<J>();
     returnValue = testToUse.CreateInstance();

     return returnValue;
 }
}