C# 单元测试IHttpActionResult不带强制转换返回类型

C# 单元测试IHttpActionResult不带强制转换返回类型,c#,asp.net,asp.net-mvc,unit-testing,C#,Asp.net,Asp.net Mvc,Unit Testing,我有一个web API控制器,其方法如下(截断的非相关位): [HttpGet] 公共IHttpActionResult订单(int orderId){ // ... var response=neworderresponse{ 数据=订单数据, 消息=消息, }; 返回Json(响应); } 我有一个测试,它对预期的JsonResult.Content的值进行断言 由于接口IHttpActionResult没有声明内容,因此我目前正在将单元测试中的结果转换为JsonResult。然而,这需要

我有一个web API控制器,其方法如下(截断的非相关位):

[HttpGet]
公共IHttpActionResult订单(int orderId){
// ...
var response=neworderresponse{
数据=订单数据,
消息=消息,
};
返回Json(响应);
}
我有一个测试,它对预期的
JsonResult.Content
的值进行断言

由于接口
IHttpActionResult
没有声明
内容
,因此我目前正在将单元测试中的结果转换为
JsonResult
。然而,这需要我的测试知道返回是如何在我的控制器中实现的,如果可能的话,我希望实现更松散的耦合,这样当响应实现发生变化时,我的测试不会中断

[TestCase(-1,“未找到请求的订单(-1)。]
public void Test返回不存在的OrderId(int OrderId,应为字符串)的NotFound{
var sut=new OrderController()
// ...
var result=sut.Order(orderId);
//我这样做是为了访问“内容”:
var materialedresult=结果为JsonResult;
应为.Should().BeEquivalentTo(materializedResult.Content.Message)
}

简而言之?仅使用界面上可用的方法

  var controller = new ValuesController();
  controller.Configuration = new System.Web.Http.HttpConfiguration();
  controller.Request = new System.Net.Http.HttpRequestMessage();
  var result = controller.Get(1);

  var response = result.ExecuteAsync(new System.Threading.CancellationToken());
  String deserialized = response.Result.Content.ReadAsStringAsync().Result;
  Assert.AreEqual("\"value\"", deserialized);

IHttpActionResult
只包含一个方法--
ExecuteAsync
。就这么说吧!它将返回一条
HttpResponseMessage
,其中将包含您要查找的内容。您可能希望使单元测试异步并实际等待结果,但这应该可以帮助您开始

不是返回
Json(响应)
,而是返回
Ok(响应)
。您不需要指定它的格式为JSON。如果客户端请求JSON,应用程序将返回JSON。(假设您使用的是默认内容协商。)

然后在单元测试中,您可以从返回的
IHttpActionResult
中检索数据,如下所示:

var actionResult = sut.Order(orderId);
var orderResponse = actionResult.ExecuteAsync(new CancellationToken())
    .Result.TryGetContentValue(out OrderResponse expected);

…您可以使用
预期的
断言任何您想要的内容,您的测试不会对响应的格式做出任何假设。

如果您不测试控制器的实际响应类型,您将测试什么?可能您可以更改为,因为最常见的结果来自此界面。我看到--我注意到有一个通用的
ReadAsAsync
,因此我将其反序列化为我的响应对象-
response.Result.Content.ReadAsAsync().Result