Squ*_*ler 14 c# unit-testing moq asp.net-core asp.net-core-webapi
我正在ASP.NET Core中构建一个Web API,我想对控制器进行单元测试.
我注入了一个数据访问接口,我可以很容易地模拟.但是控制器必须检查Request for a token中的头部,并且当我自己简单地实例化控制器时,该请求似乎不存在,并且它也是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());
}
}
Run Code Online (Sandbox Code Playgroud)
我在我的测试项目中使用Moq和MSTest,并注入一个模拟的IAccessor.如何注入请求,或使用控制器初始化它?我想我的最后一招是反思,但我真的想避免这种情况.
Nko*_*osi 20
在创建受测试控制器的实例时,请确保指定HttpContext包含所需依赖项的实例,以便完成测试.
您可以尝试模拟a 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();
//...
Run Code Online (Sandbox Code Playgroud)
以上假设您已经知道如何模拟控制器依赖关系,IAccessor并且旨在演示如何提供测试所需的框架特定依赖关系.