13

I'm trying to setup unit tests for my web API. I've hacked together some test code from bits and pieces I've found on the web. I've got as far as sending the test request off and receiving a response, but I'm stuck on testing the response.

So here's what I've got so far. This is using the xunit test package, but I don't think that matters for what I'm trying to achieve.

(Apologies for the mash of code)

[Fact]
public void CreateOrderTest()
{
    string baseAddress = "http://dummyname/";

    // Server
    HttpConfiguration config = new HttpConfiguration();
    config.Routes.MapHttpRoute("Default", "api/{controller}/{action}/{id}",
        new { id = RouteParameter.Optional });
    config.IncludeErrorDetailPolicy = IncludeErrorDetailPolicy.Always;

    HttpServer server = new HttpServer(config);

    // Client
    HttpMessageInvoker messageInvoker = new HttpMessageInvoker(new InMemoryHttpContentSerializationHandler(server));

    // Order to be created
    MotorInspectionAPI.Controllers.AccountController.AuthenticateRequest requestOrder = new MotorInspectionAPI.Controllers.AccountController.AuthenticateRequest() { 
        Username = "Test",
        Password = "password"
    };

    HttpRequestMessage request = new HttpRequestMessage();
    request.Content = new ObjectContent<MotorInspectionAPI.Controllers.AccountController.AuthenticateRequest>(requestOrder, new JsonMediaTypeFormatter());
    request.RequestUri = new Uri(baseAddress + "api/Account/Authenticate");
    request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    request.Method = HttpMethod.Get;

    CancellationTokenSource cts = new CancellationTokenSource();

    using (HttpResponseMessage response = messageInvoker.SendAsync(request, cts.Token).Result)
    {
        Assert.NotNull(response.Content);
        Assert.NotNull(response.Content.Headers.ContentType);

        // How do I test that I received the correct response?

    }

I'm hoping I can check the response as a string, something along the lines of

response == "{\"Status\":0,\"SessionKey\":"1234",\"UserType\":0,\"Message\":\"Successfully authenticated.\"}"
2
  • Where is InMemoryHttpContentSerializationHandler defined? I would like to do almost exactly what you are doing. Commented Apr 14, 2014 at 4:06
  • Never mind, BIYF. Although it was a fair way down the list of hits blogs.msdn.com/b/kiranchalla/archive/2012/05/06/… Commented Apr 14, 2014 at 4:14

3 Answers 3

20

Here is how you get your response as string:

var responseString = response.Content.ReadAsStringAsync().Result;

However json format can vary and I bet you don't want to test that - so I recommend using Newtonsoft.Json or some similar library, parse the string to json object and test json object properties instead. That'll go

using Newtonsoft.Json.Linq;   

dynamic jsonObject = JObject.Parse(responseString);
int status = (int)jsonObject.Status;
Assert.Equal(0, status);
Sign up to request clarification or add additional context in comments.

2 Comments

Thought it would be trickier than that for some reason. Thanks, this is what I was looking for. I realise about the varying data structure of the JSON, but just trying to solve one problem at a time :) EDIT: Thanks for your Newtonsoft JSON example to.
I am getting jsonObject.Status null
1

As per this blog, add an assembly reference in the AssemblyInfo.cs of your web project:

[assembly: InternalsVisibleTo("MyNamespace.Tests")]

Then, you can test as you would expect to with a normal object, except you cannot substitute "var" for the "dynamic" type:

namespace MyNamespace.Tests
// some code
       private string TheJsonMessage()
       {
           dynamic data = _json.Data;
           return data.message;
       }

It took me four hours to find that little gem.

Comments

0

If you have your expected json result, you can just use library LateApexEarlySpeed.Xunit.Assertion.Json to do "json-level" assertion (yes, it considers "varying data structure of the JSON")

JsonAssertion.Equivalent("""
                {
                  "a": 1,
                  "b": 2
                }
                """,
                """
                {
                  "b": 2,
                  "a": 1
                }
                """);

(I am author of this library)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.