一个测试的重构

    随着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 @   quitgame  阅读(484)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· [AI/GPT/综述] AI Agent的设计模式综述
点击右上角即可分享
微信分享提示