簡體   English   中英

在ASP.NET Core Controller中模擬HttpRequest

[英]Mock HttpRequest in ASP.NET Core Controller

我正在ASP.NET Core中構建Web API,並且想對控制器進行單元測試。

我為數據訪問注入了一個接口,我可以輕松地對其進行模擬。 但是控制器必須檢查Request的標頭中是否有令牌,而當我自己簡單地實例化控制器時,該Request似乎不存在,並且它也是get-only的,因此我什至無法手動設置它。 我發現了許多示例來模擬ApiController,但這不是.NET核心。 關於如何對.net核心控制器進行單元測試的許多教程和示例,但實際上都沒有使用HttpRequest。

我建立了一個MCVE來證明這一點:

[Produces("application/json")]
[Route("api/Players")]
public class PlayersController : Controller
{
    private IAccessor accessor;

    public PlayersController(IAccessor ac = null):base()
    {
        accessor = ac ?? AccessorFactory.GetAccessor();
    }

    /// <summary>
    /// Get all players. Must be logged in.
    /// </summary>
    /// <returns>Ok or Unauthorized.</returns>
    [HttpGet]
    public IActionResult Get()
    {
        Player client = accessor.GetLoggedInPlayer(Request.Headers["token"]); // NRE here because Request is null
        if (client == null) return Unauthorized();
        return Ok(accessor.GetAllPlayers());

    }
}    

我在測試項目中使用Moq和MSTest,然后注入模擬的IAccessor。 如何注入請求,或使用控制器初始化請求? 我想我的最后選擇是反思,但我真的想避免這種情況。

創建要測試的控制器的實例時,請確保分配一個HttpContext ,其中包含要執行的測試所需的依賴關系。

您可以嘗試模擬HttpContext並將其提供給控制器,或者僅使用框架提供的DefaultHttpContext

//Arrange
var mockedAccessor = new Mock<IAccessor>();
//...setup mockedAccessor behavior

//...

var httpContext = new DefaultHttpContext(); // or mock a `HttpContext`
httpContext.Request.Headers["token"] = "fake_token_here"; //Set header
 //Controller needs a controller context 
var controllerContext = new ControllerContext() {
    HttpContext = httpContext,
};
//assign context to controller
var controller = new PlayersController (mockedAccessor.Object){
    ControllerContext = controllerContext,
};

//Act
var result = controller.Get();

//...

上面的假設假設您已經知道如何模擬IAccessor之類的控制器依賴關系,並且旨在演示如何提供測試所需的特定於框架的依賴關系。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM