ASP.NET MVC3实战系列(二):面向接口编程,提高系统可测试性。

ASP.NET MVC 使用MVC的架构,其架构本身就使应用程序更易于测试,但这并不意味着可以随便写出易于测试的程序。我们都知道单元测试在系统开发有着很重要的作用。

我们来写这样的一个程序,系统获取某个坏男人的情人信息,然后发送给他老婆。

1. 建一个Lover的ASP.NET MVC3项目

image

我们需要1个实体类,存储男人,情人和老婆的信息。

image

 

然后我们需要一个LoverRepository来获取某个人的情人,这里就想成从数据库取数据。我们这里先返回固定的数据

image 

建一个HomeController, 代码如下

image

建立一个Index视图

image

建立一个Send 视图

image

F5运行

image

image

2. 重构这个小程序。

我们可以看到如果我们想测试HomeController里Send的这个Action,如果LoverRepository没有开发完或者出错,我们将无法测试

image

image

可以看到单元测试出错了。

image

那么我们如何来隔离LoveRepository呢?我们都知道面向接口编程可以提高系统的可测试性。

打开LoveRepository.cs, 右键重构为接口:

image

image

image

image

为了容易测试,我们把这个接口属性设为公有。

image

这时我们再自己可以实现一个FakeRepository继承ILoverRepository这个接口,这样就测试通过了。

image

但是这样有几个问题:

第一就是我们暴露了HomeController的repository的属性。

第二我们在类内部new了一个对象,假如我们这次是从数据库中得到Lovers,下次想从文件或者Web Service里去数据时,我们必须修改Controller里的代码。

第三我们需要自己写一个Fake类。

要想解决这些问题,下一节我们将讨论ASP.NET MVC3里如何使用IOC来解决对象的依赖问题。

 

最后,打个小广告:西安分公司急聘如下人员,有意者直接联系我,左边侧栏有我的联系方式,博客园招聘频道有详细描述 http://job.cnblogs.com/offer/13800/

基本要求:
4年以上C#开发经验, .Net基础扎实,熟练使用.Net3.5新特性。
精通ASP.NET Web开发。
熟练使用WCF.
熟练使用ORM,LINQ TO SQL /Entity Framework或者NHibernate.
熟练使用JavaScript, JQuery.
熟悉Web标准,熟悉HTML&CSS.
熟悉SQL Server, 熟练掌握T-SQL,存储过程。
英语读写熟练,可以看懂英文需求,可以和客户流畅的用英语文字沟通(MSN/Skype)
良好的编码习惯。

熟悉下面任意一项优先:
熟悉敏捷开发者优先
英语听说熟练者优先
熟悉ASP.NET MVC者优先。
熟悉WPF者优先
熟悉Silverlight优先
有系统架构经验者优先,有单元测试或者TDD经验者优先。

作者: 王德水
出处:http://www.cnblogs.com/cnblogsfans
版权:本文版权归作者和博客园共有,转载需经作者同意。

posted @ 2011-09-02 13:47 王德水 阅读(1968) 评论(5) 编辑 收藏

 回复 引用 查看   
#1楼 2011-09-02 14:05 BirchLee      
楼主是陕西人,本章不错,期待IOC
 回复 引用 查看   
#2楼 2011-09-02 14:17 Hi小鬼      
楼主头像相当猥琐!!吼吼吼吼
 回复 引用 查看   
#3楼 2011-09-02 15:44 wlf      
问题一 .二
构造函数注入+IOC 可以解决 不知道楼主用的哪个容器~

最近把 untity和 autofac 以及 Ninject, StructureMap都搞了下~~ 最后决定用autofac 觉得轻量级 而且简单好用~~

问题三 Nmork 和moq都可以~~ moq不错~

楼主文章不错 支持~ 推荐~

哈哈 还有 你的招聘条件全部都符合了(但是英语不行 只能读..)~ 包括优先那个也都OK~ 可惜人在北京~
祝楼主公司越来越好~

 回复 引用 查看   
#4楼[楼主] 2011-09-02 16:29 王德水      
@wlf
下一篇写IOC

谢谢你的祝福

 回复 引用 查看   
#5楼 2011-09-02 18:32 Scott Xu //南方小鬼      
不妨考虑用泛型 IRepository<T>() where T:class,IModel