使用Visual Studio进行单元测试-Part4
本文主要介绍Visual Studio(2012+)单元测试框架的一些技巧:
- 如何模拟类的构造函数
- 优化代码,便于测试
一、如何模拟类的构造函数
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可以分成两个
- 当输入(shapeType)为T的时候实例化Triangle类。
- 当输入为非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的更多相关文章
- 【MVC 4】4.MVC 基本工具(Visual Studio 的单元测试、使用Moq)
作者:[美]Adam Freeman 来源:<精通ASP.NET MVC 4> 3.Visual Studio 的单元测试 有很多.NET单元测试包,其中很多是开源和免费的.本 ...
- [转]Visual Studio 2010 单元测试目录
Visual Studio 2010 单元测试共分七个部分: 普通单元测试.顺序单元测试.压力测试,Generic测试.数据库测试.UI界面测试和Web性能测试. 这个系列的博客实例程序可以在下面的链 ...
- 使用Visual Studio进行单元测试
一.使用Visual Studio进行单元测试的几个建议 1.先写单元测试(依我愚见,应该是接口先行,如果有的话) -> 测试失败 -> 以最小的改动(即编写实际代码)使测试通过(而在VS ...
- Visual Studio 2010 单元测试目录
单元测试的重要性这里我就不多说了,以前大家一直使用NUnit来进行单元测试,其实早在Visual Studio 2005里面,微软就已经集成了一个叫Test的专门测试插件,经过几年的发展,这个工具现在 ...
- Visual Studio 2010 单元测试之一---普通单元测试
原文:Visual Studio 2010 单元测试之一---普通单元测试 本文以Visual Studio 2010为例,来介绍如何在Visual Studio里面进行单元测试. 首先来介绍普通单元 ...
- Visual Studio 2010 单元测试--运行测试并查看代码覆盖率
原文:Visual Studio 2010 单元测试--运行测试并查看代码覆盖率 运行测试并查看代码覆盖率对程序集中的代码运行测试时,可以通过收集代码覆盖率数据来查看正在测试的项目代码部分. 运行测试 ...
- MVC 基本工具(Visual Studio 的单元测试、使用Moq)
3.Visual Studio 的单元测试 有很多.NET单元测试包,其中很多是开源和免费的.本文打算使用 Visual Studio 附带的内建单元测试支持,但其他一些.NET单元测试包也是可用的. ...
- [转]Visual Studio 2010单元测试(2)--运行测试并查看代码覆盖率
Visual Studio 2010 单元测试--运行测试并查看代码覆盖率 运行测试并查看代码覆盖率对程序集中的代码运行测试时,可以通过收集代码覆盖率数据来查看正在测试的项目代码部分. 运行测试并查看 ...
- C# Note31: 如何使用Visual Studio做单元测试
待更! 使用Visual Studio 2013进行单元测试--初级篇 带你玩转Visual Studio——单元测试(C++例)
随机推荐
- 【bzoj2226】[Spoj 5971] LCMSum 欧拉函数
题目描述 Given n, calculate the sum LCM(1,n) + LCM(2,n) + .. + LCM(n,n), where LCM(i,n) denotes the Leas ...
- ACboy needs your help(简单DP)
HDU 1712 Problem Description ACboy has N courses this term, and he plans to spend at most M days on ...
- Amr and Chemistry
C. Amr and Chemistry time limit per test 1 second memory limit per test 256 megabytes input standard ...
- (比赛)A - Simple String Problem
A - Simple String Problem Time Limit:10000MS Memory Limit:65536KB 64bit IO Format:%lld & ...
- 论JavaWeb前后端分离放弃jsp
1.静态资源使用Nginx反向代理Tomcat,Tomcat挂了网站仍可访问.2.静态与后端服务器分离,提升性能.3.大并发情况下,可同时扩展前后端服务器.4.接口可复用至App相关服务.5.网站热部 ...
- iOS使用正则匹配限制输入密码格式
1.代码实现"密码至少为9位,并需包含大写字母.小写字母.数字或特殊字符等三种" 返回0.1.2为格式不正确,返回4为密码格式正确 -(int)checkIsHaveNumAndL ...
- php自定义函数: 计算两个时间日期相隔的天数,时,分,秒
function timediff( $begin_time, $end_time ) { if ( $begin_time < $end_time ) { $starttime = $begi ...
- LeetCode:二叉树相关应用
LeetCode:二叉树相关应用 基础知识 617.归并两个二叉树 题目 Given two binary trees and imagine that when you put one of the ...
- ubuntu14.04搭建gitlab
以下内容来自:https://mirror.tuna.tsinghua.edu.cn/help/gitlab-ce/ (清华大学开源软件镜像站)可以直接移步上面的网站.这里做个笔记,也是为了记录一下 ...
- ImportError: no module named win32api
ImportError: no module named win32api 安装win32包就好了 pip install pypiwin32