API响应强制转换时发生异常

时间:2018-10-16 13:41:51

标签: c# asp.net-core xunit

enter image description here我在单元测试用例中转换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);

但是我收到无效转换的错误。 附件是响应对象的屏幕截图 enter image description here

有关如何正确投放并解决此问题的任何建议或想法。

预先感谢

1 个答案:

答案 0 :(得分:0)

在您的控制器中,您正在执行以下操作:

return Ok(new { Response = GetWarning(Warningmessage, MessageType) });

这导致控制器用额外的“ Response”对象包装您的响应,如下所示:

{
    "response": {
        "statusCode": ...
        "message": ...
        "messageType": ...
    }
}

注意:StatusCodeMessageMessageType字段是您的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#单元测试需要强类型(即类),以便能够反序列化响应并引用测试中的属性。