本文主要介绍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. poj2485

    Highways Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 27912   Accepted: 12734 Descri ...

  2. 摘要: CentOS 6.5搭建Redis3.2.8伪分布式集群

    from https://my.oschina.net/ososchina/blog/856678     摘要: CentOS 6.5搭建Redis3.2.8伪分布式集群 前言 最近在服务器上搭建了 ...

  3. ibatis中井号跟美元符号区别(#.$)

    1.#可以进行预编译,进行类型匹配,#变量名# 会转化为 jdbc 的 类型 $不进行数据类型匹配,$变量名$就直接把 $name$替换为 name的内容 例如: select * from tabl ...

  4. 9.接口BeanPostProcessor

    package org.springframework.beans.factory.config; import org.springframework.beans.BeansException; p ...

  5. HTML-Table-Td固定宽度使内容换行

    table style="TABLE-LAYOUT: fixed;" td style="WORD-WRAP: break-word;WIDTH:200px;"

  6. 我的Android进阶之旅------>Android疯狂连连看游戏的实现之实现游戏逻辑(五)

    在上一篇<我的Android进阶之旅------>Android疯狂连连看游戏的实现之加载界面图片和实现游戏Activity(四)>中提到的两个类: GameConf:负责管理游戏的 ...

  7. 【ELK】抓取AWS-ELB日志的logstash配置文件

    前言 ELK搭建没有难度,难的是logstash的配置文件,logstash主要分为三个部分,input,filter和output. input,输入源可选的输入源由很多,详情见ELK官网,这里我们 ...

  8. linux多个分区合并为一个分区

    备份# rsync -avP -e ssh /data xxx卸载# umount /data /data?设置分区类型为8e# fdisk /dev/sdb 创建PV# pvcreate /dev/ ...

  9. 分析DNS解析时间

    提高网页的打开速度,一般地我们会选择使用CDN,利用“就近原则”让用户在最短的时间内获取到服务器资源,实际应用当中采用CDN的方式提高网站访问速度的效果也是最明显的.这也就是为什么国外的空间打开速度远 ...

  10. 第7条:用列表推导式来取代map和filter

    核心知识点: 1.列表推导式要比内置的map和filter函数清晰,因为它无需额外编写lambda表达式. 2.列表推导式可以跳过输入列表中的某些元素,如果改用map来做,那就必须辅以filter方能 ...