In your controller you are doing this:
return Ok(new { Response = GetWarning(Warningmessage, MessageType) });
This is causing the controller to wrap your response with an extra "Response" object like this:
{
"response": {
"statusCode": ...
"message": ...
"messageType": ...
}
}
NOTE: The StatusCode
, Message
and MessageType
fields are the properties on your ApiResponse
class.
But when you access the response in your test you are attempting to access it as an ApiResponse
but, because of the additional Response
field it cannot deserialize it.
The way to fix this is to change your controller return statement to:
return Ok(GetWarning(Warningmessage, MessageType));
This will change the format of the JSON response to:
{
"statusCode": ...,
"message": ...
"messageType": ...
}
Now the return type of your controller method (which is the response.Value
property) is an OkObjectResult
which means you can modify your tests to require less casting:
Assert.Equal(((int)eResp.Warn), ((ApiResponse)response.Value).StatusCode);
Assert.Equal("Please enter a unique Name.", ((ApiResponse)response.Value).Message);
Now we don't have to cast the response
object as it is already anOkObjectResult
which has the Value
property on it.
EDIT
If you need to keep the { Response: ... }
wrapper then you should use a class to do that. I would refactor your existing classes to be something like:
e.g.
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; }
}
And in your controller you would do the following:
return Ok(new ApiResponse{ Response = GetWarning(...) });
This will return the following JSON:
{
"response": {
"statusCode": 201,
"message": "All good"
"messageType: ...
}
}
And now you can use the classes we've defined in our tests to validate the controller:
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);
NOTE:
Adding an extra layer in your controller return method is fine if you are just sending the result to something that handles JSON in an easy way. Unfortunately the C# unit tests need a strong type i.e. a class, to be able to deserialize the response and reference the properties in the test.