0

对采用泛型类型参数的抽象类进行单元测试的正确方法是什么,其中类型也是抽象类?例如)

public abstract class BaseClass<T> where T : BaseT { ... }

我必须创建一个扩展 BaseT 的测试类,对吗?

如果 BaseClass 支持方法链接会发生什么

public abstract class BaseClass<T> where T : BaseClass<T> { ... } ??

谢谢。

更新了第二种情况的具体类样本:

    public class ConcreteClass : BaseClass<ConcreteClass>
    {
        public ConcreteClass Method1()
        {
            return this as ConcreteClass;
        }
    }
4

3 回答 3

3

您可以在不使用 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();
    }
}

您可以通过以下方式测试 Concrete 的实现:

[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 就是您可以使用的模拟框架。

于 2010-11-01T16:49:46.523 回答
1

在不知道更多细节的情况下,我猜您正在尝试测试在抽象泛型类中实现的一些代码。例如,您可以测试在基类中实现且未标记为抽象的公共方法或属性。

因此,您必须创建一个扩展通用基类 BaseClass< T > 的类和一个扩展 BaseT 的不同类。我们分别称它们为 ConcreteClass< T > 和 ConcreteT。

然后,实例化一个类型为 ConcreteClass<ConcreteT> 的类。您现在可以在此实例上运行测试,允许您测试抽象类的逻辑。

于 2010-11-01T20:05:16.057 回答
0

没有办法测试抽象类,你不能创建一个实例:)

于 2010-11-01T16:38:25.640 回答