What would be the proper way to unit test an abstract class which takes generic type parameter where the type is also an abstract class? E.g)
public abstract class BaseClass<T> where T : BaseT { ... }
I'll have to create a test class which extends BaseT, right??
and what happen if the BaseClass support method chaining such that
public abstract class BaseClass<T> where T : BaseClass<T> { ... } ??
thanks.
updated concrete class sample for the 2nd case:
public class ConcreteClass : BaseClass<ConcreteClass>
{
public ConcreteClass Method1()
{
return this as ConcreteClass;
}
}
You can do this without implementing a dummy implementation class using Rhino Mocks: http://www.ayende.com/wiki/Rhino+Mocks+Partial+Mocks.ashx
Unfortunately, Rhino Mocks requires you to use the record/playback syntax with partial mocks instead of the AAA syntax.
Given the following abstract classes:
public abstract class BaseAbstract
{
public abstract int Increment();
}
public abstract class AbstractClass<T> where T : BaseAbstract
{
private int inc;
public abstract T Abstract();
public virtual int Concrete()
{
return inc += Abstract().Increment();
}
}
You can test the implementation of Concrete in the following way:
[Test]
public void mock_an_abstract_class_with_generic()
{
var mocks = new MockRepository();
var baseAbstract = mocks.StrictMock<BaseAbstract>();
var abstractClass = mocks.PartialMock<AbstractClass<BaseAbstract>>();
using (mocks.Record())
{
baseAbstract.Stub(a => a.Increment()).Return(5);
abstractClass.Stub(a => a.Abstract()).Return(baseAbstract);
}
using (mocks.Playback())
{
abstractClass.Concrete().ShouldEqual(5);
abstractClass.Concrete().ShouldEqual(10);
}
}
In essence, you create a partial mock for the base class, set expectations on the abstract methods, then call the concrete method under test. The generic is simply another mock, another partial if necessary.
The downside of this is obviously the requirement for the record/playback syntax. I don't know if other mocking frameworks can help you out more here, but I've generally found that Rhino Mocks is the mocking framework you go to if you have an advanced use case like this.