本文主要介绍Visual Studio(2012+)单元测试框架的一些技巧:

  1. 如何模拟类的构造函数
  2. 优化代码,便于测试

一、如何模拟类的构造函数

1.1 被测代码

基础代码,IShape分别有Rectangle和Triangle俩个子类。有一个简单的CalculateArea方法。

namespace BlogDemo.UTDemo
{
public interface IShape
{
int CalculateArea();
} class Rectangle : IShape
{
public int CalculateArea()
{
return ;
}
} class Triangle : IShape
{
public int CalculateArea()
{
return ;
}
}
}

被测试的类:该类根据传入的参数不同而调用不同的子类进行操作。

class App
{
public void Calculate(string shapeType)
{
if (shapeType == "T")
{
new Triangle().CalculateArea();
}
else
{
new Rectangle().CalculateArea();
}
}
}

1.2 测试目标

现在要测试App类的Calculatef方法,测试该类的case可以分成两个

  1. 当输入(shapeType)为T的时候实例化Triangle类。
  2. 当输入为非T的时候实例化Rectangle类。

上面的测试主要是为了测试这个if的调度是否正确,而不关心Calculate到底做了什么。所以上面测试的验证不应该通过CalculateArea的值来进行验证,因为这违反了单元测试的“单元”二字。

1.3 测试代码

在ms.test框架下,可以通过ShimClassName.Constuctor来模拟类名为ClassName的类的构造函数

[TestClass]
public class AppTests
{
[TestMethod]
public void CalculateTest()
{
using (ShimsContext.Create())
{
var triangleConstructed = false;
ShimTriangle.Constructor = (@this) =>//此处模拟Triangle类的构造函数,如果Triangle被实例化,则triangleConstructed为true
{
triangleConstructed = true;
}; var rectangleConstructed = false;
ShimRectangle.Constructor = (@this) =>//此处模拟Rectangle类的构造函数,如果Rectangle被实例化,则rectangleConstructed为true
{
rectangleConstructed = true;
}; App.Calculate("T");
Assert.IsFalse(rectangleConstructed);
Assert.IsTrue(triangleConstructed);
}
}
}

因为App.Calculate("T");所以Triangle类被实例化(triangleConstructed为true),而Rectangle类没有被实例化(rectangleCOnstructed为false)。

相反,得下面的测试结果:

  [TestClass]
public class AppTests
{
[TestMethod]
public void CalculateTest()
{
using (ShimsContext.Create())
{
var triangleConstructed = false;
ShimTriangle.Constructor = (@this) =>//此处模拟Triangle类的构造函数,如果Triangle被实例化,则triangleConstructed为true
{
triangleConstructed = true;
}; var rectangleConstructed = false;
ShimRectangle.Constructor = (@this) =>//此处模拟Rectangle类的构造函数,如果Rectangle被实例化,则rectangleConstructed为true
{
rectangleConstructed = true;
}; App.Calculate("F");//非T。Rectangle将会被实例化
Assert.IsTrue(rectangleConstructed);
Assert.IsFalse(triangleConstructed);
}
}
}

二、代码优化。

在TTD中有一种说法叫做代码不可测试,其实要不是ms.test框架的Shim功能强大,上面的代码其实是不可测试的。上面的代码完全可以进行优化。

2.1 优化后的代码

  public class App
{
public static void Calculate(string shapeType)
{
var shape = CreateShape(shapeType);
shape.CalculateArea();
} public static IShape CreateShape(string shapeType)
{
if (shapeType == "T")
{
return new Triangle();
}
else
{
return new Rectangle();
}
}
}

上面使用一个简单工场先构建一个IShape对象,这样这个构建过程以方法的形式公布出来,可以就这个CreateShape方法进行单独测试。

2.2 优化后的测试代码

        [TestMethod]
public void CreateShape_TriangleConstructed_Test()
{
var shape = App.CreateShape("T");
Assert.AreEqual(shape.GetType(), typeof(Triangle));
} [TestMethod]
public void CreateShape_RectangleConstructed_Test()
{
var shape = App.CreateShape("F");
Assert.AreEqual(shape.GetType(), typeof(Rectangle));
}

简单调整了一下代码,测试代码就变的非常简单,且非常清晰,当然针对优化后的代码之前使用Shim方式的测试代码还是可以继续运行的。

三、结论

使用微软的测试框架很多之前“不能测试”的代码依然可以继续测试,但是这不是好习惯,测试不应该过于依赖测试框架的feature。而是应该在测试的过程中慢慢调整代码,让代码变的可“测试”。

使用Visual Studio进行单元测试-Part4的更多相关文章

  1. 【MVC 4】4.MVC 基本工具(Visual Studio 的单元测试、使用Moq)

     作者:[美]Adam Freeman      来源:<精通ASP.NET MVC 4> 3.Visual Studio 的单元测试 有很多.NET单元测试包,其中很多是开源和免费的.本 ...

  2. [转]Visual Studio 2010 单元测试目录

    Visual Studio 2010 单元测试共分七个部分: 普通单元测试.顺序单元测试.压力测试,Generic测试.数据库测试.UI界面测试和Web性能测试. 这个系列的博客实例程序可以在下面的链 ...

  3. 使用Visual Studio进行单元测试

    一.使用Visual Studio进行单元测试的几个建议 1.先写单元测试(依我愚见,应该是接口先行,如果有的话) -> 测试失败 -> 以最小的改动(即编写实际代码)使测试通过(而在VS ...

  4. Visual Studio 2010 单元测试目录

    单元测试的重要性这里我就不多说了,以前大家一直使用NUnit来进行单元测试,其实早在Visual Studio 2005里面,微软就已经集成了一个叫Test的专门测试插件,经过几年的发展,这个工具现在 ...

  5. Visual Studio 2010 单元测试之一---普通单元测试

    原文:Visual Studio 2010 单元测试之一---普通单元测试 本文以Visual Studio 2010为例,来介绍如何在Visual Studio里面进行单元测试. 首先来介绍普通单元 ...

  6. Visual Studio 2010 单元测试--运行测试并查看代码覆盖率

    原文:Visual Studio 2010 单元测试--运行测试并查看代码覆盖率 运行测试并查看代码覆盖率对程序集中的代码运行测试时,可以通过收集代码覆盖率数据来查看正在测试的项目代码部分. 运行测试 ...

  7. MVC 基本工具(Visual Studio 的单元测试、使用Moq)

    3.Visual Studio 的单元测试 有很多.NET单元测试包,其中很多是开源和免费的.本文打算使用 Visual Studio 附带的内建单元测试支持,但其他一些.NET单元测试包也是可用的. ...

  8. [转]Visual Studio 2010单元测试(2)--运行测试并查看代码覆盖率

    Visual Studio 2010 单元测试--运行测试并查看代码覆盖率 运行测试并查看代码覆盖率对程序集中的代码运行测试时,可以通过收集代码覆盖率数据来查看正在测试的项目代码部分. 运行测试并查看 ...

  9. C# Note31: 如何使用Visual Studio做单元测试

    待更! 使用Visual Studio 2013进行单元测试--初级篇 带你玩转Visual Studio——单元测试(C++例)

随机推荐

  1. Collecting Bugs (概率dp)

    Ivan is fond of collecting. Unlike other people who collect post stamps, coins or other material stu ...

  2. rpc接口和http接口的区别和联系

    1 什么是http接口 http接口是基于http协议的post和get接口. 2 什么是rpc接口 rpc接口就相当于调用本地接口一样调用远程服务的接口. 3 常用的rpc框架 thrift 自动代 ...

  3. Swift URL encode

    前言 在WEB前端开发,服务器后台开发,或者是客户端开发中,对URL进行编码是一件很常见的事情,但是由于各个年代的RFC文档中的内容一直在变化,一些年代久远的代码就对URL编码和解码的规则和现在的有一 ...

  4. flex 坐标系

    全局坐标(舞台坐标)  本地坐标 内容坐标系  地图坐标(MapPoint) flash和flex针对不同的目的,提供了3种不同的坐标系 全局的就是(stage级别的) 本地坐标系(组件级别的) 内容 ...

  5. Python 3 mysql 数据类型

    Python 3 mysql 数据类型 存储引擎决定了表的类型,而表内存放的数据也要有不同的类型,每种数据类型都有自己的宽度,但宽度是可选的 详细参考: http://www.runoob.com/m ...

  6. webpack打包笔记

    optimist是一个node库,将webpack.config.js与shell参数整合成options对象 options对象包含之后构建的重要信息,类似于webpack.config.js we ...

  7. Understanding Linux File Permissions

    Although there are already a lot of good security features built into Linux-based systems, one very ...

  8. 算法(Algorithms)第4版 练习 2.1.1

    E A S Y Q U E S T I O N A E S Y Q U E S T I O N A E S Y Q U E S T I O N A E E Y Q U S S T I O N A E ...

  9. JVM中垃圾回收算法

    GC 算法与种类 GC的概念 Garbage Collection 垃圾收集1960年 List 使用了GCJava中,GC的对象是堆空间和永久区 引用计数法 老牌垃圾回收算法通过引用计算来回收垃圾使 ...

  10. 大话设计模式--状态模式 State -- C++实现实例

    1.状态模式: 当一个对象的内在状态改变时,允许改变其行为,这个对象看起来就像是改变了其类. 状态模式解决的是当控制一个对象状态转换的条件表达式过于复杂, 把状态的判断逻辑转移到表示不同状态的一系列类 ...