ASP.NET Core 单元测试:如何 Mock HttpContext.Features.Get()
點擊上方藍字關注“汪宇杰博客”
導語
在 ASP.NET Core 里,如果你想單元測試 HttpContext.Features.Get<SomeType>(),這個技巧一定不要錯過。
問題
我有個 Error 頁面,需要取得異常的詳細信息。我使用?HttpContext.Features.Get<IExceptionHandlerPathFeature>() 方法。
public void OnGet()
{
? ? var requestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier;
? ? var exceptionFeature = HttpContext.Features.Get<IExceptionHandlerPathFeature>();
? ? if (exceptionFeature is not null)
? ? {
? ? ? ? // Get which route the exception occurred at
? ? ? ? var routeWhereExceptionOccurred = exceptionFeature.Path;
? ? ? ? // Get the exception that occurred
? ? ? ? var exceptionThatOccurred = exceptionFeature.Error;
? ? ? ? _logger.LogError($"Error: {routeWhereExceptionOccurred}, " +
? ? ? ? ? ? ? ? ? ? ? ? ?$"client IP: {HttpContext.Connection.RemoteIpAddress}, " +
? ? ? ? ? ? ? ? ? ? ? ? ?$"request id: {requestId}", exceptionThatOccurred);
? ? }
? ? RequestId = requestId;
}
現在,我需要單元測試這段代碼。通常,在需要 HttpContext的 Page 或 Controller 中,我會使用?DefaultHttpContext 的實例。但我發現 HttpContext 上的 Features 屬性是只讀的。因此沒有辦法將 mock 好的對象賦值給它。
namespace Microsoft.AspNetCore.Http
{
? ? public abstract class HttpContext
? ? {
? ? ? ? protected HttpContext();
? ? ? ? //
? ? ? ? // Summary:
? ? ? ? //? ? ?Gets the collection of HTTP features provided by the server and middleware available
? ? ? ? //? ? ?on this request.
? ? ? ? public abstract IFeatureCollection Features { get; }
? ? ? ? //? ...
? ? }
}
解決辦法
首先,像平常一樣準備 mock。在我的案例里,我需要配置?IFeatureCollection.Get() 方法,返回我想要的對象。
var mockIFeatureCollection = _mockRepository.Create<IFeatureCollection>();
mockIFeatureCollection.Setup(p => p.Get<IExceptionHandlerPathFeature>())
? ? .Returns(new ExceptionHandlerFeature
? ? {
? ? ? ? Path = "/996/icu",
? ? ? ? Error = new("Too much fubao")
? ? });
httpContextMock.Setup(p => p.Features).Returns(mockIFeatureCollection.Object);
下下來,為了給 HttpContext.Features 賦值,我們這次不能使用 DefaultHttpContext 了。我們需要創建 HttpContext 自己的 mock,并且配置 Features 屬性返回剛才 mock 的 IFeatureCollection 對象。
var httpContextMock = _mockRepository.Create<HttpContext>();
httpContextMock.Setup(p => p.Features).Returns(mockIFeatureCollection.Object);
現在運行單元測試,我們可以看到正確的值已經輸出了。
汪宇杰博客
Azure | .NET |?微軟 MVP
無廣告,不賣課,做純粹的技術公眾號
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的ASP.NET Core 单元测试:如何 Mock HttpContext.Features.Get()的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hosting in .NET Core
- 下一篇: mini api