如何正确测试抽象类

我目前正在为一个名为Component的抽象类创建unit testing。 VS2008编译我的程序没有问题所以我能够在解决方案中创建一个unit testing项目。 但是,我注意到的一件事是,在创建测试文件时,有一些我以前从未见过的方法:

 internal virtual Component CreateComponent() { // TODO: Instantiate an appropriate concrete class. Component target = null; return target; } internal virtual Component_Accessor CreateComponent_Accessor() { // TODO: Instantiate an appropriate concrete class. Component_Accessor target = null; return target; } 

我认为这些是用于创建具体的Component类。

在每个Test方法中,都有这一行:

Component target = CreateComponent(); // TODO: Initialize to an appropriate value

如何将其初始化为适当的值? 或者,如何通过CreateComponentCreateComponent_Accessor方法实例化一个适当的具体类?

这里是抽象类的构造函数,有关其他信息:

protected Component(eVtCompId inComponentId, eLayer inLayerId, IF_SystemMessageHandler inMessageHandler)

您无法实例化抽象类。 因此,您可以在unit testing项目中编写此抽象类的模拟实现(您应该在其中实现抽象成员),然后调用您尝试测试的方法。 您可以使用不同的模拟实现来测试类的各种方法。

作为编写模拟实现的替代方法,您可以使用模拟框架,例如Rhino Mocks,Moq,NSubstitute,……这可以简化此任务并允许您定义对类的抽象成员的期望。


更新:

根据评论部分的要求,这是一个例子。

假设您有以下要进行unit testing的抽象类:

 public abstract class FooBar { public abstract string Foo { get; } public string GetTheFoo() { return "Here's the foo " + Foo; } } 

现在,在您的unit testing项目中,您可以通过编写实现具有模拟值的抽象成员的派生类来实现它:

 public class FooBarMock : FooBar { public override string Foo { get { return "bar" } } } 

然后你可以针对GetTheFoo方法编写unit testing:

 // arrange var sut = new FooBarMock(); // act var actual = sut.GetTheFoo(); // assert Assert.AreEqual("Here's the foo bar", actual); 

并且使用模拟框架(在我的示例中为Moq),您不需要在unit testing中实现此抽象类,但您可以直接使用模拟框架来定义被测方法依赖的抽象成员的期望:

 // arrange var sut = new Mock(); sut.Setup(x => x.Foo).Returns("bar"); // act var actual = sut.Object.GetTheFoo(); // assert Assert.AreEqual("Here's the foo bar", actual);