Вы можете сделать это без реализации фиктивного класса реализации, используя Rhino Mocks: http://www.ayende.com/wiki/Rhino+Mocks+Partial+Mocks.ashx
К сожалению, Rhino Mocks требует использования синтаксиса записи / воспроизведения с частичными имитациями вместо синтаксиса AAA.
Даны следующие абстрактные классы:
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();
}
}
Вы можете проверить реализацию Бетона следующим образом:
[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);
}
}
По сути, вы создаете частичный макет для базового класса, устанавливаете ожидания для абстрактных методов, а затем вызываете конкретный тестируемый метод. Универсальный просто другой макет, другой частичный, если необходимо.
Недостатком этого является, очевидно, требование к синтаксису записи / воспроизведения. Я не знаю, могут ли другие фреймворки помочь вам в этом, но я обычно обнаружил, что Rhino Mocks - это фреймворк, к которому вы обращаетесь, если у вас есть такой продвинутый вариант использования.