I have an ASP.NET MVC controller endpoint of type ActionResult that returns a ViewResult by calling Controller.View(<some html>).
When integration testing this endpoint is it possible to convert the HttpResponseMessage to a ViewResult?
Unfortunately, there is no support for direct conversion from HttpResponseMessage to ViewResult.
Implementation:
using System.Net;
public class ApiReponseModel<T>
{
public HttpStatusCode StatusCode { get; private set; }
public string ResponseMessage { get; private set; }
public T Data { get; private set; }
public ApiReponseModel(HttpStatusCode statusCode)
{
StatusCode = statusCode;
}
public ApiReponseModel(HttpStatusCode statusCode, T data)
{
StatusCode = statusCode;
Data = data;
}
public ApiReponseModel(HttpStatusCode statusCode, string responseMessage)
{
StatusCode = statusCode;
ResponseMessage = responseMessage;
}
public ApiReponseModel(HttpStatusCode statusCode, string responseMessage, T data)
{
StatusCode = statusCode;
ResponseMessage = responseMessage;
Data = data;
}
}
HttpResponseMessage to ViewResult.using Newtonsoft.Json;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Mvc;
public static class ViewResultHelper
{
public static async Task<ViewResult> ToViewResultAsync<T>(
this HttpResponseMessage response,
string viewName,
string errorViewName = "/Views/Shared/Error.cshtml")
{
if (!response.IsSuccessStatusCode)
{
var errorRespContentString = await response.Content.ReadAsStringAsync();
return new ViewResult
{
ViewName = errorViewName,
ViewData = new ViewDataDictionary()
{
Model = new ApiReponseModel<T>
(
response.StatusCode,
response.ReasonPhrase,
JsonConvert.DeserializeObject<T>(errorRespContentString)
)
}
};
}
var respContentString = await response.Content.ReadAsStringAsync();
return new ViewResult
{
ViewName = viewName,
ViewData = new ViewDataDictionary()
{
Model = new ApiReponseModel<T>
(
response.StatusCode,
JsonConvert.DeserializeObject<T>(respContentString)
)
}
};
}
}
/* Mocked response */
/*
User user = new User { Name = "Test User" };
var response = new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(JsonConvert.SerializeObject(user), Encoding.UTF8, "application/json")
};
*/
return await response.ToViewResultAsync<User>("<Your View Name>");
Model with ApiReponseModel<T> type.@model /* Your Project namespace */.Models.ApiReponseModel<User>
@using Newtonsoft.Json
<!-- To get API response body data -->
<code>
@JsonConvert.SerializeObject(Model.Data, Formatting.Indented)
</code>
Controller.View(<some html>)- I don't see an overload accepting HTML, can you please give some more details, maybe a minimal reproducible example? But if I understand your case correctly (and I probably don't), then no, you will have the generated HTML for view result in yourHttpResponseMessage. If you want to test theViewResultitself you need to setup the controller context and call theYourController.YourActionas a simple method, not via the HTTP. For HTTP - you need to analyze the generated HTML.