我已经编写了这个 Controller 方法和这个测试。
Controller 方法:
public async Task<IActionResult> Metric(string type, string source)
{
// Check existence ...
var model = await _context
.Metrics
.FirstAsync(mt => mt.Type == metricType.AsInt() && mt.Source == source);
Response.StatusCode = HttpStatusCode.OK.AsInt();
return View(model);
}
测试:
[Fact]
public async Task MetricExistsTest()
{
// Arrange ...
// Act
var result = await _controller.Metric(Metrics.CpuLoad.ToString(), "source-1");
// Assert
var viewResult = Assert.IsType<ViewResult>(result);
Assert.Equal(HttpStatusCode.OK.AsInt(), viewResult.StatusCode.Value);
var model = Assert.IsAssignableFrom<Metric>(
viewResult.ViewData.Model
);
}
现在,问题就在这里 Assert.Equal(HttpStatusCode.OK.AsInt(), viewResult.StatusCode.Value);
。 viewResult.StatusCode
确实是 null
。如果我注释掉那一行,一切正常。
我做错了什么?为什么它是 null
?我是否正确设置了 Response.StatusCode
?那么如何验证状态码呢?
谢谢!
最佳答案
我终于做到了! 所有帮助我回答和评论的人 - 我非常感谢!
事实证明我有两个问题 - HttpContext
在测试环境中不存在(除非手动设置)并且 Response.StatusCode
没有设置 StatusCode
在生成的 ViewResult
对象上。 (这些是我的观察,如果我错了请纠正我)。
问题1解决方案:
设置默认 HttpContext
就可以解决问题。至少, Controller 方法不会崩溃,因为 Response
不再是 null
。
var controller = new HomeController();
controller.ControllerContext = new ControllerContext();
controller.ControllerContext.HttpContext = new DefaultHttpContext();
问题2解决方案:
事实证明,我需要在 ViewResult
对象上显式设置 StatusCode
。出于某种原因,ASP.Core 不会将 StatusCode
从 Response
对象镜像到生成的 IActionObject
。 (如果我错了请纠正我)
所以这是解决方案(这是我 Controller 上的另一种方法,但它清楚地展示了这个想法):
public async Task<IActionResult> Index()
{
var model = await _context
.Metrics
.Where(mt => mt.Type == Metrics.CpuLoad.AsInt())
.ToListAsync();
var result = View(model);
result.StatusCode = (model.Any() ? HttpStatusCode.OK : HttpStatusCode.NoContent).AsInt();
return result;
}
关于c# - ViewResult.StatusCode 为空,尽管已明确设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42424969/