如何对抽象类进行单元测试

45

在 Visual Studio 中使用了创建单元测试工具,显然它试图实例化我的抽象类。

我的问题是:我应该尝试按照 Visual Studio 推荐的方式进行单元测试吗?还是应该创建用于实例化的模拟类,或者仅测试使用此抽象类的方法?

谢谢。

5个回答

87
如果这个抽象类中有值得测试的方法,则应该对它们进行测试。您可以为测试子类化该抽象类(并将其命名为MyAbstractClassTesting),并测试这个新的具体类。

34

有两种截然不同的观点:

  • 不要测试抽象类本身,而是测试从它继承而来的具体类。
  • 应该测试抽象类,因为它提供了一些内置逻辑,这些逻辑在所有继承类之间共享,因此您只需要在抽象类中测试基础逻辑一次。

我更喜欢第二个选项(目前)并使用RhinoMocks PartialMock 功能测试抽象类,它允许我创建一个抽象类的模拟对象。


8
  1. 只需测试实现类。

  2. 您可以始终创建一个特定的实现来进行测试,该实现不添加任何额外的功能。

  3. 听取测试结果。使用模拟工具来对抽象类和私有方法等进行测试是一种测试代码异味。


0

使用 mockrepository:

[testmethod]
       public void testwithmockrepository()
       {
           var mockrepository = new rhino.mocks.mockrepository();
           var mock = mockrepository.partialmock<myabstractclass>();

           using ( mockrepository.record() )
           {
               expect.call( mock.dosomething( arg<string>.is.anything ) ).return( "hi..." ).repeat.once();
           }
           using ( mockrepository.playback() )
           {
               assert.areequal( "hi..." , mock.dosomething( "salam" ) );
           }
       }

-1
我不会测试抽象类,因为有一个非常简单的原因:实现类可能有自己的某些方法实现 - 如果你测试抽象类,你就不知道后续代码的实际行为。 此外,如果你测试抽象类的已实现方法,那么你就将你的测试与抽象类的实现绑定在一起 - 但是你不能创建抽象类的对象,那么这样的测试有什么用呢? :)

所有编写的代码都应该有测试,无论它是否被使用。如果您有覆盖某些抽象实现的实现,您也必须测试这些实现,而不能跳过抽象实现。 - Darkproduct
如果一个抽象类实现了任何方法,那么这个方法应该被测试。这并不难理解。抽象类可以有方法实现,这些实现可以被类实现覆盖。这意味着,你必须确保测试抽象类的原始实现。 - Darkproduct
这就是你不必在抽象类中测试的原因!你已经派生了抽象类,你没有重写那个已实现的方法并且你在你的派生类的测试中测试这个方法,结果将是正确的。但你测试的是派生类而不是抽象类。但我猜你可以有很多不同的方法,试图找到“黄金蛋”就像讨论什么更好:C# 还是 Java :) - Eru

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接