C# 如何模拟Request.Url.GetLeftPart(),使单元测试通过

C# 如何模拟Request.Url.GetLeftPart(),使单元测试通过,c#,asp.net,unit-testing,C#,Asp.net,Unit Testing,我的代码就是这样做的 string domainUrl = HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority); int result = string.Compare(domainUrl, "http://www.facebookmustdie.com"); // do something with the result... 我如何模拟它,使我的单元测试通过,我必须模拟整个HttpContext类吗?如果是这样

我的代码就是这样做的

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基本上有两种可能性:

  • 使用或模拟
    HttpContext
  • 为整个
    HttpContext
    类或仅为UrlHelper引入接口,并将实现该接口的类的实例传递到类中。关键词:依赖注入(DI)

  • HttpContext单例不能轻易模仿,也不能很好地进行单元测试,因为它将您与IIS基础设施联系在一起

    的确,鼹鼠也可以做这项工作,但真正的问题是与IIS的严重耦合


    您应该将相关的请求数据(在您的例子中是url)传递给您的函数或类,以便能够将您的逻辑与基础结构隔离开来。通过这种方式,您将能够将其与IIS分离,并在测试基础设施上轻松运行。

    我不知道您编写此代码的目的是什么类型的项目,但如果是MVC项目,我建议您重新编写代码,改用HttpContextBase—如果可能的话。然后,您可以创建一个存根或模拟,并为您的测试注入该存根或模拟。Request.Url返回System.Uri,因此您必须创建此实例并在上下文存根/mock上设置它。

    上述示例:

    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 :)
          }
       }
    }
    

    第二部分是依赖注入。第1部分(共2部分)是一个适配器。这很好,我不知道你可以这样做,我将来肯定可以使用它,我没有将此标记为答案的唯一原因是因为我重新思考了我的设计,并因此能够改进它。你可以模拟或使用存根,你必须决定要做什么。
    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 :)
          }
       }
    }