2013-03-04 74 views
3

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

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类。

在每个测试方法,有这样一行:

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

我怎么初始化这个适当的值?或者,我如何实例化一个合适的具体类,如上面的CreateComponentCreateComponent_Accessor方法所述?

这里是抽象类的构造函数,额外的信息:

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

回答

11

你不能实例化一个抽象类。所以你可以在你的单元测试项目中编写这个抽象类的模拟实现(你应该在那里实现抽象成员),然后调用你正在测试的方法。你可以有不同的模拟实现来测试你的类的各种方法。

作为替代编写模拟实现,你可以使用mock框架,如犀牛嘲笑,起订量,NSubstitute,......这能简化这一任务,并允许您定义类的抽象成员的期望。


UPDATE:

正如在评论部分要求在这里是一个例子。

让我们假设你有你想要的单元测试下面的抽象类:

public abstract class FooBar 
{ 
    public abstract string Foo { get; } 

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

现在,在你的单元测试项目,你可以通过编写一个派生类实现与嘲笑值的抽象成员实现:

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

,然后你可以编写针对GetTheFoo方法单元测试:

// arrange 
var sut = new FooBarMock(); 

// act 
var actual = sut.GetTheFoo(); 

// assert 
Assert.AreEqual("Here's the foo bar", actual); 

并且使用模拟框架(在我的例子中为Moq),你不需要在单元测试中实现这个抽象类,但是你可以直接使用模拟框架来定义被测方法依赖的抽象成员的期望值:

// arrange 
var sut = new Mock<FooBar>(); 
sut.Setup(x => x.Foo).Returns("bar"); 

// act 
var actual = sut.Object.GetTheFoo(); 

// assert 
Assert.AreEqual("Here's the foo bar", actual); 
+0

只是为了澄清,与_mock实现你的意思是这个抽象class_的,创建一个派生类,并实现所有抽象成员... – DHN 2013-03-04 08:25:41

+1

这将是非常有益的,如果你会告诉我这两个模拟实现的一些例子并使用一个模拟框架(我有Moq框架,一直在使用它的接口) – Anthony 2013-03-04 08:25:51

+0

当然,我已经更新了我的答案,为您提供一个示例。 – 2013-03-04 08:39:24