2011-03-09 56 views
3

我的代码做这个我怎么能嘲笑Request.Url.GetLeftPart(),所以我的单元测试通过

string domainUrl = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority); 
int result = string.Compare(domainUrl, "http://www.facebookmustdie.com"); 
// do something with the result... 

我怎么能嘲笑这个,所以我的单元测试通过,我必须嘲笑整个HttpContext类?如果这是我怎么会注入到这一点的代码,这样的“正确”的HttpContext当单元测试运行

+0

你可以嘲笑或使用存根,你必须决定你想要做什么。 – 2012-10-17 20:39:54

回答

2

HttpContext单例不能轻易被模拟,并且在单元测试中也不能很好地运行,因为它将您与IIS基础结构联系在一起。

这是真的,痣可以做的工作太多,但真正的问题是重couplage与IIS。

您应该将相关的请求数据(您的案例中的url)传递给您的函数或类,以便能够将您的逻辑从基础结构中分离出来。这样一来,你就可以将其从IIS分开,并在测试基础架构上运行很容易。

0

基本上被使用,有两种可能的情况:

  1. 使用TypeMock IsolatorMoles到模拟HttpContext
  2. 介绍的接口为全HttpContext类或只是一个UrlHelper并通过实现该接口到你的类的类的实例。关键字:依赖注入(DI)
+0

的2第二部分是依赖注入。 2的第一部分是一个适配器。 – 2011-03-09 17:14:02

0

我不知道是什么类型的项目,你写的这个代码,但如果它是一个MVC项目,我会建议重新编写代码时使用HttpContextBase而不是 - 如果可能的话。然后你可以创建一个存根或模拟这个并为你的测试注入它。 Request.Url返回的System.Uri所以你必须创建这样一个实例,并设置你的背景存根/模拟。

12

You don't need to mock it:

 var sb = new StringBuilder(); 
     TextWriter w = new StringWriter(sb); 
     var context = new HttpContext(new HttpRequest("", "http://www.example.com", ""), new HttpResponse(w)); 

     HttpContext.Current = context; 

     Console.WriteLine(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority)); 
+1

这很好,我不知道你能做到这一点,我一定能够在将来使用它,我没有把这个标记为答案的唯一原因是因为我重新思考了我的设计,因此能够改善它。 – Rob 2011-03-10 10:53:02

0

例以上:

namespace Tests 
{ 
    [TestClass()] 
    public class MyTests 
    { 
     [ClassInitialize()] 
     public static void Init(TestContext context) 
     { 
     // mock up HTTP request 
     var sb = new StringBuilder(); 
     TextWriter w = new StringWriter(sb); 
     var httpcontext = new HttpContext(new HttpRequest("", "http://www.example.com", ""), new HttpResponse(w)); 

     HttpContext.Current = httpcontext; 

     } 
     [TestMethod()] 
     public void webSerivceTest() 
     { 
     // the httpcontext will be already set for your tests :) 
     } 
    } 
}