我正在尝试在web api 2中创建一个自定义的IHttpActionResult类型,它将以HTML而不是json的形式返回内容。我正在努力的是如何对返回我的新ActionResult类型的ApiController进行单元测试。许多显示如何对ApiController进行单元测试的示例告诉您将其强制转换为OkNegotiatedContentResult,然后从中读取内容属性,但这似乎不适用于我的情况。当我调试测试时,似乎永远不会调用ExecuteAsync中的代码块。我是否需要在单元测试中明确地执行此操作?任何帮助都会很有帮助
这就是我的ActionResult的样子
public class HtmlActionResult : IHttpActionResult
{
String _html;
public HtmlActionResult(string html)
{
_html = html;
}
public Task<System.Net.Http.HttpResponseMessage> ExecuteAsync(System.Threading.CancellationToken cancellationToken)
{
var response = new HttpResponseMessage(HttpStatusCode.OK);
response.Content = new StringContent(_html );
response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("text/html");
return Task.FromResult(response);
}
}
这是我的ApiController
public class HomeController : ApiController
{
public IHttpActionResult Get(string page)
{
return new HtmlActionResult("<html></html>");
}
}
这是我的测试方法
[TestMethod]
public async Task Get()
{
//Arrenge
HomeController controller = new HomeController();
//Act
IHttpActionResult result = controller.Get();
//Assert
//Assert.IsNotNull(result.Content);
}
答案 0 :(得分:4)
IHttpActionResult result = await controller.Get()
HtmlActionResult htmlActionResult = result.Should()
.BeOfType<HtmlActionResult>()
.Which; // <-- the key feature
// or .And
什么意思可以嵌套断言:
IHttpActionResult result = await controller.Get()
result.Should().BeOfType<HtmlActionResult>()
.Which.Content.Should().Be(expected);
或者就像@Spock分别建议测试一样:
答案 1 :(得分:2)
您不是在等待控制器操作完成 - 您应该将测试更改为(这是未经验证的):
public async Task Get()
{
// Arrange
HomeController controller = new HomeController();
// Act
IHttpActionResult result = await controller.Get();
// Assert
Assert.IsNotNull(result.Content);
}
答案 2 :(得分:1)
试试这个:
[TestMethod]
public void Get()
{
//Arrenge
var controller = new HomeController();
//Act
var result = controller.Get().Result as HtmlActionResult;
//Assert
Assert.IsNotNull(result);
}
请注意,您的测试可能无效,并且您不必等待Get方法,您可以使用.Result来运行任务。
此外,我将结果转换为HtmlActionResult,如果结果是一个不同的ActionResult,如OkResult,或NotFoundResult,等等,结果将为Null。
希望有所帮助。
答案 3 :(得分:1)
假设您正在使用WebAPI版本2,那么有关如何在The ASP.NET Site上单元测试控制器的非常好的指南。
我遇到了类似的情况,并且让我的控制器方法返回Tasks
而不是IHttpActionResults
有点不确定 - 我相信它更清晰。
我设法在上面链接的测试操作返回HttpResponseMessage 部分调整代码,以使我的单元测试按预期工作。
以下是我的方案的简要概述:
public class XyzController : ApiController
{
private readonly IDbContext _dbContext;
public XyzController(IDbContext dbContext)
{
_dbContext = dbContext;
}
[HttpGet]
[Route("this-is-optional")]
public IHttpActionResult Get(<optional-params-here>)
{
// Do work
...
// My data is an array of objects
return Ok(data);
}
}
[TestFixture]
public class XyzControllerTest
{
[Test]
public void Get_ReturnsSuccessfully()
{
// Arrange
IDbContext testContext = MockDbContext.Create();
...
// Populate textContext here
...
XyzController xyzController = new XyzController(testContext)
{
// These are required or exceptions will be thrown
Request = new HttpRequestMessage();
Configuration = new HttpConfiguration()
};
...
// Act
var response = xyzController.Get(<params-if-required>).ExecuteAsync(CancellationToken.None);
// Assert
Assert.IsNotNull(response);
Assert.IsTrue(response.IsCompleted);
Assert.AreEqual(HttpStatusCode.OK, response.Result.StatusCode);
// Assertions on returned data
MyModel[] models;
Assert.IsTrue(response.Result.TryGetContentValue<MyModel[]>(out models));
Assert.AreEqual(5, model.Count());
Assert.AreEqual(1, model.First().Id);
...
}
}