一个测试的重构

    随着TDD的流行,单元测试越来越成为软件开发的重要组成部分。那么,说到单元测试,大家都会想到NUnit(当然还有CPPUnit等,不过不在本文的讨论范围)。在NUnit中,编写一个测试的Class是很简单的,不需要像JUnit中那样从某个Class继承,这也得益于 DotNet中富有创意的 Attribute 特性。通过Attribute ,便有了不需要从BaseClass继承的 NUnit,便有了不需要使用Xml辅助配置的ORM工具---GroveKit 。在DotNet中,只需要将Class标记TestFixtureAttribute ,这个Class将被NuitFramework发现,并自动调用其中标记有TestAttribute 的方法作为测试方法。所以,在我为一个排序算法编写Test的时候,它大概就是这样的:

   

using System;
using NUnit.Framework;

namespace Sorter.TestCase
{
    
/**//// <summary>
    
/// 冒泡算法的测试类
    
/// </summary>

      [TestFixture]
    
public abstract class TestSortBase
    
{
        
protected  BubbleSorter sorter ;
         
        [SetUp]
        
public void SetUp()
        
{
            sorter 
= new BubbleSorter();
        }


         

        [Test]
         
public void TestIntSort()
        
{
            
// some Assert here
        }


        [Test]
         
public void TestDoubleSort()
        
{
            
// some Assert here
        }


        [Test]
         
public void TestDateTimeSort()
        
{
            
// some Assert here
        }


        [Test]
         
public void TestStringSort()
        
{
            
// some Assert here
        }


        [Test]
        [ExpectedException(
typeof(ArgumentException))]
         
public void TestException()
        
{
            
// some Assert here
        }

    }





         
这个测试类看起来工作的让我满意,在我的算法出现问题的时候,总能被它发现。
冒泡排序是最简单的排序算法,接下来我需要为我的 快速插入排序编写单元测试。首先我想到的是,将上面的类中出现的所有 BubbleSorter 替换为 InsertSorter ,但是很明显,你已经闻到了代码的 Bad Smell了。重复的代码总是让人产生厌恶 。
         
我试着将BubbleSorter的声明改为SorterBase,SetUp方法声明为virtual,然后我让我的InsertSorterBubbleSorter继承,并重写了SetUp。这似乎解决了问题,但是很明显,InsertSorterBubbleSorter之间不应该是继承的关系,而应该是兄弟的关系。
       
怎么办呢?也许你早就想到了,提炼出一个TestBase,让InsertSorterBubbleSorter从它继承。没错,我提炼了一个抽象类,这在重构名录中大概叫做Extract Super Class,其实,重构就像是设计模式一样,在你知道它是一种经典的重构之前,你已经在大量使用这种方法了。这个TestBase应该是抽象类,因为它也不应该实例化。还有一点,标记为abstractclass,即使被标记TestFixtureAttribute,并且内部含有Test方法,在执行测试的时候,也会被NUnit忽略。但是,为了减轻NUnit的工作量,我还是去除了TestBaseTestFixtureAttribute,这样,代码阅读者也不至于产生误解。
       
下面是经过重构后的TestBubbleSorter  

       

    ///<summary>
    
/// 冒泡排序的测试类
    
/// </summary>

    [TestFixture]
    
public class TestBubbleSorter : TestSortBase
    
{
        
protected override SorterBase CreateSorter()
        
{
            
return SorterFactory.GetSorter( typeof( BubbleSorter ) );
        }

     }



       
至于SortBase是啥样的,我想地球人都知道了。

posted @ 2005-10-15 15:18  quitgame  阅读(479)  评论(0编辑  收藏  举报