0

I have a controller that uses Newtonsoft.Json to convert IEnumerable into JSON format.

[Route("")]
public IHttpActionResult Get()
{
    IEnumerable<Product> productList = ProductService.GetAllProducts();
    if (!productList.Any())
        return Ok();

    return Json(productList, new JsonSerializerSettings
    {
        ContractResolver = new WebContractResolver(),
        Converters = new List<JsonConverter> { new TrimStringDataConverter() }
    });
}

When I hit the API end point through POSTMAN, it gives me the expected JSON data.

[
    {
        "code": "prod101",
        "title": "LAPTOP"
    },
    {
        "code": "prod102",
        "title": "MOBILE"
    }
]

Now, I am writing unit test(NUnit) for the controller and I want to get this JSON formatted data in my unit test method. I am able to get the IEnumerable -

IHttpActionResult actionResult = mockProductControllerClient.Get();
JsonResult<IEnumerable<Product>> contentResult = actionResult as JsonResult<IEnumerable<Product>>;
IEnumerable<Product> data = contentResult.Content;

I need the exact same data in Unit Test methods as being received in POSTMAN i.e. JSON data

shahidbits
  • 121
  • 10
  • 2
    `I need the exact same data in Unit Test methods as being received in POSTMAN` Why do you need that? _That is ASP.NET's job, to JSON encode the data. Your unit test doesn't need to test it._ – mjwills Feb 06 '18 at 10:40
  • You can do an In-memory integration test which can look like it came from postman – Nkosi Feb 06 '18 at 10:43
  • 1
    Why are you testing the controller, or your controllers ability to return JSON. Surely you only want to test that your product list is valid. – developer Feb 06 '18 at 10:44
  • For Asp.Net Web API 2.* you can do something like this from a previous answer I wrote https://stackoverflow.com/a/37510032/5233410 – Nkosi Feb 06 '18 at 10:51
  • @mjwills: I want to test out cases like json keys are in camel-cased ? – shahidbits Feb 06 '18 at 21:11
  • @Nkosi: Right. I can do that but I am wondering if I can get JSON in unit test. – shahidbits Feb 06 '18 at 21:12
  • @developer: I need to test the json keys. Actually, the ContractResolver being used does some stuff like include JsonProperty annotated properties only, do a camel-case of json keys etc. I want to check if I am sending the right data and in the expected json format or not. – shahidbits Feb 06 '18 at 21:15
  • In WebAPI2 - you dont need to wrap response for JSON - the action will return what the requests content-type(mime-type) specified - which is most likely where you issue lies. You must specify the type: i.e. "application/json" And in your controller action you can just: return this.Ok(); and it will be Json. if your request has "application/xml" it will return XML. – developer Feb 07 '18 at 11:22
  • @developer: I agree. I am getting the desired results once the response is disposed off the pipeline. I am getting JSON in my client/postman as mentioned in my question. What I want is to get this json in a method that calls up the controller's method Get(). – shahidbits Feb 12 '18 at 05:59

1 Answers1

2

I found the answer -

IHttpActionResult keeps the SerializerSettings stored which might be applied down the pipeline when the response is disposed off.

In the unit test, since we are taking data from controller i.e. in middle of the pipeline, we will have to apply SerializerSettings ourselves. So, first step is the extract the IEnumerable from action result -

IHttpActionResult actionResult = MockController.Get();
JsonResult<IEnumerable<Product>> contentResult = actionResult as JsonResult<IEnumerable<Product>>;

And then, apply the serializer settings and get your json -

string responseString = JsonConvert.SerializeObject(contentResult.Content, contentResult.SerializerSettings);
JArray responseJson = JArray.Parse(responseString);

Hope, this would help others.

shahidbits
  • 121
  • 10