c# - ASP.NET Core Controller 中的模拟 HttpRequest

标签 c# unit-testing asp.net-core moq asp.net-core-webapi

我正在 ASP.NET Core 中构建 Web API,我想对 Controller 进行单元测试。

我注入(inject)了一个数据访问接口(interface),我可以很容易地模拟它。但是controller要检查Request中的header是否有token,我自己简单实例化controller时那个Request好像不存在,而且也是get-only,所以我连手动设置都做不到。我找到了很多模拟 ApiController 的示例,但这不是 .NET 核心。还有许多关于如何对 .net 核心 Controller 进行单元测试的教程和示例,但实际上没有一个使用 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,并注入(inject)了一个模拟的 IAccessor。如何注入(inject)请求,或使用 Controller 对其进行初始化?我想我最后的选择是反射(reflection),但我真的想避免这种情况。

最佳答案

在创建被测 Controller 的实例时,请确保分配一个 HttpContext,其中包含执行测试所需的依赖项。

您可以尝试模拟一个 HttpContext 并将其提供给 Controller ,或者只使用框架提供的 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();

//...

以上假设您已经知道如何模拟 Controller 依赖项,例如 IAccessor,旨在演示如何提供测试所需的框架特定依赖项。

关于c# - ASP.NET Core Controller 中的模拟 HttpRequest,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50116753/

相关文章:

c# - 为什么字典查找比递归搜索慢?

c# - 改进 LINQ 查询返回满足特定条件的项目的索引

c# - ASP.NET 4.5 或替代框架中的 OpenIdDict?

c# - .net Core 6 WebApi 对象中的调解器处置异常

c# - 与 MahAppsMetro ProgressIndicator 绑定(bind)失败

Java 电源模拟单元测试具有 Thread.Sleep 的方法

javascript - 如何使用 Angular 8 单元测试检查图像是否存在于给定路径中?

c# - Caliburn.微单元测试

c# - 在 ASP.NET Core 中启用来自同一 session 的并发请求

c# - Azure - WebAPI 无法连接到 Azure DB,错误 : The system cannot find the file specified [SqlException]