使用Fakes的Stub和Shim对ASP.NET MVC4进行单元测试
这是一篇导航文,不是翻译。
MSDN对stub和shim的解释和使用场景演示:http://msdn.microsoft.com/en-us/library/hh549175.aspx
一个更详细的示例:http://www.richonsoftware.com/post/2012/04/05/Using-Stubs-and-Shim-to-Test-with-Microsoft-Fakes-in-Visual-Studio-11.aspx
我感兴趣的是如何对mvc项目进行测试:http://www.richonsoftware.com/post/2012/05/02/Noninvasive-Unit-Testing-in-ASPNET-MVC-A-Microsoft-Fakes-Deep-Dive.aspx
里面讲的内容分别有:
1,利用shim来重写第三方类库或系统类库的方法
[TestMethod]
public void TestLogOff()
{
var accountController = new AccountController();
var formsAuthenticationSignOutCalled = false;
RedirectToRouteResult redirectToRouteResult; //Scope the detours we're creating
using (ShimsContext.Create())
{
//Detours FormsAuthentication.SignOut() to an empty implementation
ShimFormsAuthentication.SignOut = () =>
{
//Set a boolean to identify that we actually got here
formsAuthenticationSignOutCalled = true;
};
redirectToRouteResult = accountController.LogOff() as RedirectToRouteResult;
Assert.AreEqual(true, formsAuthenticationSignOutCalled);
} Assert.NotNull(redirectToRouteResult);
Assert.AreEqual("Index", redirectToRouteResult.RouteValues["Action"]);
Assert.AreEqual("Home", redirectToRouteResult.RouteValues["controller"]);
}
2,怎么判断该用stub
[TestMethod]
public void TestLogin()
{
string testUserName = "TestUserName";
string testPassword = "TestPassword";
bool testRememberMe = false;
string returnUrl = "/foo.html"; var loginModel = new LoginModel
{
UserName = testUserName,
Password = testPassword,
RememberMe = testRememberMe
}; var accountController = new AccountController(); //Setup underpinning via stubbing such that UrlHelper
//can validate that our "foo.html" is local
var stubHttpContext = new StubHttpContextBase();
var stubHttpRequestBase = new StubHttpRequestBase();
stubHttpContext.RequestGet = () => stubHttpRequestBase;
var requestContext = new RequestContext(stubHttpContext, new RouteData());
accountController.Url = new UrlHelper(requestContext); RedirectResult redirectResult;
//Scope the detours we're creating
using (ShimsContext.Create())
{
//Sets up a detour for Membership.ValidateUser to our mocked implementation
ShimMembership.ValidateUserStringString = (userName, password) =>
{
Assert.AreEqual(testUserName, userName);
Assert.AreEqual(testPassword, password);
return true;
}; //Sets up a detour for FormsAuthentication.SetAuthCookie to our mocked implementation
ShimFormsAuthentication.SetAuthCookieStringBoolean = (userName, rememberMe) =>
{
Assert.AreEqual(testUserName, userName);
Assert.AreEqual(testRememberMe, rememberMe);
}; redirectResult = accountController.Login(loginModel, returnUrl) as RedirectResult;
} Assert.NotNull(redirectResult);
Assert.AreEqual(redirectResult.Url, returnUrl);
}
3,如何还原动态对象
[TestMethod]
public void TestInvalidJsonLogin()
{
string testUserName = "TestUserName";
string testPassword = "TestPassword";
bool testRememberMe = false;
string testReturnUrl = "TestReturnUrl"; var loginModel = new LoginModel
{
UserName = testUserName,
Password = testPassword,
RememberMe = testRememberMe
}; var accountController = new AccountController();
JsonResult jsonResult;
//Scope the detours we're creating
using (ShimsContext.Create())
{
//Sets up a detour for Membership.ValidateUser to our mocked implementation
ShimMembership.ValidateUserStringString = (userName, password) => false;
jsonResult = accountController.JsonLogin(loginModel, testReturnUrl);
}
//答案在这里
var errors = (IEnumerable<string>)(new PrivateObject(jsonResult.Data, "errors")).Target;
Assert.AreEqual("The user name or password provided is incorrect.", errors.First());
4,如何给请求添加上下文,及如何在请求中加入用户对象
[TestMethod]
public void TestChangePassword()
{
string testUserName = "TestUserName";
string testOldPassword = "TestOldPassword";
string testNewPassword = "TestNewPassword"; var changePasswordModel = new ChangePasswordModel
{
OldPassword = testOldPassword,
NewPassword = testNewPassword
}; var accountController = new AccountController(); //Stub HttpContext
var stubHttpContext = new StubHttpContextBase();
//Setup ControllerContext so AccountController will use our stubHttpContext
accountController.ControllerContext = new ControllerContext(stubHttpContext,
new RouteData(), accountController); //Stub IPrincipal
var principal = new StubIPrincipal();
principal.IdentityGet = () =>
{
var identity = new StubIIdentity { NameGet = () => testUserName };
return identity;
};
stubHttpContext.UserGet = () => principal; RedirectToRouteResult redirectToRouteResult;
//Scope the detours we're creating
using (ShimsContext.Create())
{
ShimMembership.GetUserStringBoolean = (identityName, userIsOnline) =>
{
Assert.AreEqual(testUserName, identityName);
Assert.AreEqual(true, userIsOnline); var memberShipUser = new ShimMembershipUser();
//Sets up a detour for MemberShipUser.ChangePassword to our mocked implementation
memberShipUser.ChangePasswordStringString = (oldPassword, newPassword) =>
{
Assert.AreEqual(testOldPassword, oldPassword);
Assert.AreEqual(testNewPassword, newPassword);
return true;
};
return memberShipUser;
}; var actionResult = accountController.ChangePassword(changePasswordModel);
Assert.IsInstanceOf(typeof(RedirectToRouteResult), actionResult);
redirectToRouteResult = actionResult as RedirectToRouteResult;
}
Assert.NotNull(redirectToRouteResult);
Assert.AreEqual("ChangePasswordSuccess", redirectToRouteResult.RouteValues["Action"]);
}
上面种种,文章给的不仅仅是答案,更有思考过程,比如问题原因,可能的解决方法,以及最后给一个最优的方法,值得一读的。
使用Fakes的Stub和Shim对ASP.NET MVC4进行单元测试的更多相关文章
- ASP.NET 系列:单元测试
单元测试可以有效的可以在编码.设计.调试到重构等多方面显著提升我们的工作效率和质量.github上可供参考和学习的各种开源项目众多,NopCommerce.Orchard等以及微软的asp.net m ...
- ASP.Net MVC4+Memcached+CodeFirst实现分布式缓存
ASP.Net MVC4+Memcached+CodeFirst实现分布式缓存 part 1:给我点时间,允许我感慨一下2016年 正好有时间,总结一下最近使用的一些技术,也算是为2016年画上一个完 ...
- CentOS上 Mono 3.2.8运行ASP.NET MVC4经验
周一到周三,折腾了两天半的时间,经历几次周折,在小蝶惊鸿的鼎力帮助下,终于在Mono 3.2.8上运行成功MVC4.在此总结经验如下: 系统平台的版本: CentOS 6.5 Mono 3.2.8 J ...
- ASP.NET MVC4入门到精通系列目录汇总
序言 最近公司在招.NET程序员,我发现好多来公司面试的.NET程序员居然都没有 ASP.NET MVC项目经验,其中包括一些工作4.5年了,甚至8年10年的,许多人给我的感觉是:工作了4.5年,We ...
- [MVC4]ASP.NET MVC4+EF5(Lambda/Linq)读取数据
继续上一节初始ASP.NET MVC4,继续深入学习,感受了一下微软的MVC4+EF5(EntityFramework5)框架的强大,能够高效的开发出网站应用开发系统,下面就看一下如何用MVC4+EF ...
- 21、ASP.NET MVC入门到精通——ASP.NET MVC4优化
本系列目录:ASP.NET MVC4入门到精通系列目录汇总 删除无用的视图引擎 默认情况下,ASP.NET MVCE同时支持WebForm和Razor引擎,而我们通常在同一个项目中只用到了一种视图引擎 ...
- 最新版CentOS6.5上安装部署ASP.NET MVC4和WebApi
最新版CentOS6.5上安装部署ASP.NET MVC4和WebApi 使用Jexus5.8.1独立版 http://www.linuxdot.net/ ps:该“独立版”支持64位的CentOS ...
- Asp.Net MVC4 + Oracle + EasyUI 学习 第二章
Asp.Net MVC4 + Oracle + EasyUI 第二章 --使用Ajax提升网站性能 本文链接:http://www.cnblogs.com/likeli/p/4236723.html ...
- Asp.Net MVC4 + Oracle + EasyUI 学习 第一章
Asp.Net MVC4 + Oracle + EasyUI 第一章 --操作数据和验证 本文链接:http://www.cnblogs.com/likeli/p/4234238.html 文章集合 ...
随机推荐
- C#学习笔记(5)——大项目查找
说明(2017-5-27 16:34:39): 1. 注意事项: (0)设计窗体,添加一个dgv,添加5个列名,修改名字和绑定数据. (1)添加引用,system.data.sqlclient (2) ...
- YII登陆错误 mcrypt_create_iv()
使用php框架YII进行开发的时候,虽然很快,性能很好,但是也有一些小问题,现在记录下来. 1.在使用gii的自动代码生成后,登陆系统,就会报错 mcrypt_create_iv() [<a h ...
- Python的自增运算符
今天在写一个合并两个有血list的时候,使用了while循环,不自觉的使用了i++,自测的时候发现有语法错误,还检查了好几遍,觉得应该没啥错误啊,后来google了一把,恍然大悟,原来Python早就 ...
- ExecutorService中submit和execute的区别<转>
在Java5之后,并发线程这块发生了根本的变化,最重要的莫过于新的启动.调度.管理线程的一大堆API了.在Java5以后,通过Executor来启动线程比用Thread的start()更好.在新特征中 ...
- 小措施提高Linux服务器安全
禁止root远程登录 作为默认系统管理账号root是最容易攻击的目标.禁止通过ssh远程登录是绝对必须的. 方法: 编辑 /etc/ssh/sshd_config PermitRootLogin no ...
- Sublime Text 3 安装与配置
1.下载: http://www.sublimetext.com/3 2.支持网站 https://packagecontrol.io/ 3.字体.主题风格等设置 当需要更改主题时,直接可以通过“pr ...
- Php5.5新特性 Generators详解
在PHP5.5.0版本中,新增了生成器(Generators)特性,用于简化实现迭代器接口(Iterator)创建简单的迭代器的复杂性. 通过生成器,我们可以轻松的使用foreach迭代一系列的数据, ...
- Python 文件操作三
文件重命名os模块中的rename()可以完成对文件的重命名操作rename(需要修改的文件名, 新的文件名) import os os.rename("11.txt", &quo ...
- 【SIP协议】学习初学笔记
1.SIP这玩意是怎么走来和如何构建的? 通俗的说,SIP就是一个轻量级信令协议,它可以作为音频.视频.及时信息的信令. 说到SIP是怎么出来的就要提H.323,而提到这个标准由不得不提到ITU-T, ...
- 磁盘映射: between 宿主机 and 客户机
一.虚拟机映射到宿主机 在虚拟机关机的状态下,双击右侧设备栏里硬盘,在弹出的窗口中单击“实用程序“,选择“映射”.打开映射虚拟磁盘的窗口,其中的“卷”就是你希望映射虚拟机中的哪个分区到主机,如 ...