我在单元测试用例中转换API响应以测试API调用时遇到问题。
我正在使用以下行比较响应状态代码。
Assert.Equal(((int)eResp.Warn), ((ApiResponse)((ObjectResult)response).Value).StatusCode);
我正在使用以下行比较验证消息。
Assert.Equal("Please enter a unique Name.", ((ApiResponse)((ObjectResult)response).Value).Message);
下面一行返回控制器的响应
return Ok(new { Response = GetWarning(Warningmessage, MessageType) });
GetWarning方法返回如下响应
return new ApiResponse((int)HttpStatusCode.Accepted, warningMessage, MessageType);
有关如何正确投放并解决此问题的任何建议或想法。
预先感谢
答案 0 :(得分:0)
在您的控制器中,您正在执行以下操作:
return Ok(new { Response = GetWarning(Warningmessage, MessageType) });
这导致控制器用额外的“ Response”对象包装您的响应,如下所示:
{
"response": {
"statusCode": ...
"message": ...
"messageType": ...
}
}
注意:StatusCode
,Message
和MessageType
字段是您的ApiResponse
类的属性。
但是,当您在测试中访问响应时,您试图以ApiResponse
的形式访问它,但是由于附加了Response
字段,它无法反序列化它。
解决此问题的方法是将控制器的return语句更改为:
return Ok(GetWarning(Warningmessage, MessageType));
这会将JSON响应的格式更改为:
{
"statusCode": ...,
"message": ...
"messageType": ...
}
现在,控制器方法的返回类型(即response.Value
属性)是OkObjectResult
,这意味着您可以修改测试以减少铸造工作:
Assert.Equal(((int)eResp.Warn), ((ApiResponse)response.Value).StatusCode);
Assert.Equal("Please enter a unique Name.", ((ApiResponse)response.Value).Message);
现在我们不必强制转换response
对象,因为它已经是具有OkObjectResult
属性的Value
。
编辑
如果需要保留{ Response: ... }
包装器,则应使用一个类来完成。我会将您现有的类重构为:
例如
public class ApiResponse
{
public Response Response { get; set; }
}
public class Response
{
public int StatusCode { get; set; }
public string Message { get; set; }
public string MessageType { get; set; }
}
在控制器中,您将执行以下操作:
return Ok(new ApiResponse{ Response = GetWarning(...) });
这将返回以下JSON:
{
"response": {
"statusCode": 201,
"message": "All good"
"messageType: ...
}
}
现在您可以使用在测试中定义的类来验证控制器:
var result = controller.Get(); // this is your controller call
var apiResponse = result.Value as ApiResponse;
Assert.AreEqual(201, apiResponse.Response.StatusCode);
Assert.AreEqual("All good", apiResponse.Response.Message);
注意: 如果您只是将结果发送到以简单方式处理JSON的内容,则可以在控制器的return方法中添加额外的层。不幸的是,C#单元测试需要强类型(即类),以便能够反序列化响应并引用测试中的属性。