Moq:对依赖 HttpContext 的方法进行单元测试 [英] Moq: unit testing a method relying on HttpContext

查看:35
本文介绍了Moq:对依赖 HttpContext 的方法进行单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑 .NET 程序集中的一个方法:

Consider a method in a .NET assembly:

public static string GetSecurityContextUserName()
{             
 //extract the username from request              
 string sUser = HttpContext.Current.User.Identity.Name;
 //everything after the domain     
 sUser = sUser.Substring(sUser.IndexOf("\") + 1).ToLower();

 return sUser;      
}

我想从使用 Moq 框架的单元测试中调用此方法.此程序集是 webforms 解决方案的一部分.单元测试看起来像这样,但我缺少 Moq 代码.

I'd like to call this method from a unit test using the Moq framework. This assembly is part of a webforms solution. The unit test looks like this, but I am missing the Moq code.

//arrange 
 string ADAccount = "BUGSBUNNY";
 string fullADName = "LOONEYTUNESBUGSBUNNY"; 

 //act    
 //need to mock up the HttpContext here somehow -- using Moq.
 string foundUserName = MyIdentityBL.GetSecurityContextUserName();

 //assert
 Assert.AreEqual(foundUserName, ADAccount, true, "Should have been the same User Identity.");

问题:

  • 我怎样才能使用 Moq 来安排一个带有诸如MyDomainMyUser"之类的值的假 HttpContext 对象?
  • 我如何将这个伪造与我在 MyIdentityBL.GetSecurityContextUserName() 中对静态方法的调用相关联?
  • 您对如何改进此代码/架构有什么建议吗?
  • How can I use Moq to arrange a fake HttpContext object with some value like 'MyDomainMyUser'?
  • How do I associate that fake with my call into my static method at MyIdentityBL.GetSecurityContextUserName()?
  • Do you have any suggestions on how to improve this code/architecture?

推荐答案

Webforms 是出了名的不可测试,正是因为这个原因 - 许多代码可以依赖于 asp.net 管道中的静态类.

Webforms is notoriously untestable for this exact reason - a lot of code can rely on static classes in the asp.net pipeline.

为了使用 Moq 进行测试,您需要重构您的 GetSecurityContextUserName() 方法以使用带有 HttpContextBase 对象的依赖注入.

In order to test this with Moq, you need to refactor your GetSecurityContextUserName() method to use dependency injection with an HttpContextBase object.

HttpContextWrapper 驻留在 System.Web.Abstractions 中,它随 .Net 3.5 一起提供.它是HttpContext 类的包装器,并扩展了HttpContextBase,您可以像这样构造一个HttpContextWrapper:

HttpContextWrapper resides in System.Web.Abstractions, which ships with .Net 3.5. It is a wrapper for the HttpContext class, and extends HttpContextBase, and you can construct an HttpContextWrapper just like this:

var wrapper = new HttpContextWrapper(HttpContext.Current);

更好的是,您可以模拟 HttpContextBase 并使用 Moq 设置您对它的期望.包括登录用户等

Even better, you can mock an HttpContextBase and set up your expectations on it using Moq. Including the logged in user, etc.

var mockContext = new Mock<HttpContextBase>();

有了这个,您可以调用 GetSecurityContextUserName(mockContext.Object),并且您的应用程序与静态 WebForms HttpContext 的耦合要少得多.如果您要进行大量依赖模拟上下文的测试,我强烈建议 采取看看 Scott Hanselman 的 MvcMockHelpers 类,它有一个用于 Moq 的版本.它可以方便地处理许多必要的设置.尽管有这个名字,你不需要用 MVC 来做 - 当我可以重构它们以使用 HttpContextBase 时,我成功地将它与 webforms 应用程序一起使用.

With this in place, you can call GetSecurityContextUserName(mockContext.Object), and your application is much less coupled to the static WebForms HttpContext. If you're going to be doing a lot of tests that rely on a mocked context, I highly suggest taking a look at Scott Hanselman's MvcMockHelpers class, which has a version for use with Moq. It conveniently handles a lot of the setup necessary. And despite the name, you don't need to be doing it with MVC - I use it successfully with webforms apps when I can refactor them to use HttpContextBase.

这篇关于Moq:对依赖 HttpContext 的方法进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆