Asp.net

如何在 ASP.NET 5 / MVC 6 的單元測試中訪問 HttpContext

  • December 11, 2016

假設我在中間件的 http 上下文上設置了一個值。例如 HttpContext.User。

如何在我的單元測試中測試 http 上下文。這是我正在嘗試做的一個例子

中間件

public class MyAuthMiddleware
{
   private readonly RequestDelegate _next;

   public MyAuthMiddleware(RequestDelegate next)
   {
       _next = next;
   }

   public async Task Invoke(HttpContext context)
   {
       context.User = SetUser(); 
       await next(context);
   }
}

測試

[Fact]
public async Task UserShouldBeAuthenticated()
{
   var server = TestServer.Create((app) => 
   {
       app.UseMiddleware<MyAuthMiddleware>();
   });

   using(server)
   {
       var response = await server.CreateClient().GetAsync("/");
       // After calling the middleware I want to assert that 
       // the user in the HttpContext was set correctly
       // but how can I access the HttpContext here?
   }
}

asp.net 5/MVC6 的 RC1 版本使得在單元測試中手動設置 HttpContext 成為可能,太棒了!

       DemoController demoController = new DemoController();
       demoController.ActionContext = new ActionContext();
       demoController.ActionContext.HttpContext = new DefaultHttpContext();
       demoController.HttpContext.Session = new DummySession();

DefaultHttpContext 類由平台提供。DummySession 可以只是實現 ISession 類的簡單類。這大大簡化了事情,因為不再需要模擬。

如果您將中間件類與其餘程式碼隔離開來對中間件類進行單元測試,那就更好了。

由於HttpContext類是一個抽像類,因此您可以使用模擬框架Moq"Moq": "4.2.1502.911",作為依賴項添加到 project.json 文件)來驗證是否設置了使用者屬性。

例如,您可以編寫以下測試來驗證您的中間件Invoke函式是否在 httpContext 中設置 User 屬性並呼叫下一個中間件:

[Fact]
public void MyAuthMiddleware_SetsUserAndCallsNextDelegate()
{
   //Arrange
   var httpContextMock = new Mock<HttpContext>()
           .SetupAllProperties();
   var delegateMock = new Mock<RequestDelegate>();
   var sut = new MyAuthMiddleware(delegateMock.Object);

   //Act
   sut.Invoke(httpContextMock.Object).Wait();

   //Assert
   httpContextMock.VerifySet(c => c.User = It.IsAny<ClaimsPrincipal>(), Times.Once);
   delegateMock.Verify(next => next(httpContextMock.Object), Times.Once);
}

然後,您可以編寫額外的測試來驗證使用者是否具有預期值,因為您將能夠通過以下方式獲取設置的 User 對象httpContextMock.Object.User

Assert.NotNull(httpContextMock.Object.User);
//additional validation, like user claims, id, name, roles

引用自:https://stackoverflow.com/questions/30557521