当它返回IHttpActionResult时,如何unit testingweb api操作方法?

我们假设这是我的行动方法

public IHttpActionResult Get(int id) { var status = GetSomething(id); if (status) { return Ok(); } else { return NotFound(); } } 

testing将是

 var httpActionResult = controller.Get(1); 

如何在此之后检查我的http状态码?

这里Ok()只是OkResulttypes的帮助器, OkResult响应状态设置为OkResult …所以你可以检查你的动作结果的实例是否是OkResult …一些例子(用OkResult写的) :

 // if your action returns: NotFound() IHttpActionResult actionResult = valuesController.Get(10); Assert.IsType<NotFoundResult>(actionResult); // if your action returns: Ok() actionResult = valuesController.Get(11); Assert.IsType<OkResult>(actionResult); // if your action was returning data in the body like: Ok<string>("data: 12") actionResult = valuesController.Get(12); OkNegotiatedContentResult<string> conNegResult = Assert.IsType<OkNegotiatedContentResult<string>>(actionResult); Assert.Equal("data: 12", conNegResult.Content); // if your action was returning data in the body like: Content<string>(HttpStatusCode.Accepted, "some updated data"); actionResult = valuesController.Get(13); NegotiatedContentResult<string> negResult = Assert.IsType<NegotiatedContentResult<string>>(actionResult); Assert.Equal(HttpStatusCode.Accepted, negResult.StatusCode); Assert.Equal("some updated data", negResult.Content); 

时间来复活一个死的问题

当前的答案都依赖于将响应对象转换为已知的types。 不幸的是,这些响应似乎没有一个可用的层次结构或隐式转换path,无法深入了解控制器的实现。 考虑以下:

 public class MixedCodeStandardController : ApiController { public readonly object _data = new Object(); public IHttpActionResult Get() { return Ok(_data); } public IHttpActionResult Get(int id) { return Content(HttpStatusCode.Success, _data); } } 

testing类:

 var testController = new MixedCodeStandardController(); var getResult = testController.Get(); var posRes = getResult as OkNegotiatedContentResult<object>; Assert.IsType<OkNegotiatedContentResult<object>>(getResult); Assert.AreEqual(HttpStatusCode.Success, posRes.StatusCode); Assert.AreEqual(testController._data, posRes.Content); var idResult = testController.Get(1); var oddRes = getResult as OkNegotiatedContentResult<object>; // oddRes is null Assert.IsType<OkNegotiatedContentResult<object>>(idResult); // throws failed assertion Assert.AreEqual(HttpStatusCode.Success, oddRes.StatusCode); // throws for null ref Assert.AreEqual(testController._data, oddRes.Content); // throws for null ref 

从黑盒子外面看,响应stream本质上是一样的。 testing必须知道控制器如何执行callback以这种方式进行testing。

而是使用返回的IHttpActionResult中的HttpResponseMessage对象。 这确保了testing可以是一致的,即使控制器代码可能不是:

 var testController = new MixedCodeStandardController(); var getResult = testController.Get(); var getResponse = getResult.ExecuteAsync(CancellationToken.None).Result; Assert.IsTrue(getResponse.IsSuccessStatusCode); Assert.AreEqual(HttpStatusCode.Success, getResponse.StatusCode); var idResult = testController.Get(1); var idResponse = idResult.ExecuteAsync(CancellationToken.None).Result; Assert.IsTrue(idResponse.IsSuccessStatusCode); Assert.AreEqual(HttpStatusCode.Success, idResponse.StatusCode); 

这是Kiran Challa公认的答案,适用于NUnit;

 var valuesController = controller; // if your action returns: NotFound() IHttpActionResult actionResult = valuesController.Get(10); var notFoundRes = actionResult as NotFoundResult; Assert.IsNotNull(notFoundRes); // if your action returns: Ok() actionResult = valuesController.Get(11); var posRes = actionResult as OkResult; Assert.IsNotNull(posRes); // if your action was returning data in the body like: Ok<string>("data: 12") actionResult = valuesController.Get(12); var conNegResult = actionResult as OkNegotiatedContentResult<string>; Assert.IsNotNull(conNegResult); Assert.AreEqual("data: 12", conNegResult.Content); // if your action was returning data in the body like: Content<string>(HttpStatusCode.Accepted, "some updated data"); actionResult = valuesController.Get(13); var negResult = actionResult as NegotiatedContentResult<string>; Assert.IsNotNull(negResult); Assert.AreEqual(HttpStatusCode.Accepted, negResult.StatusCode); Assert.AreEqual("some updated data", negResult.Content);