1

I'm brand new to unit testing and I need to do this for a current project. I have plenty of examples for testing model classes and MVC controllers, but I have a couple of web API controllers that have a Json return that I need to unit test. What should I be testing with these, and how can I do that?

First example taking no parameters

public class DefaultController : ApiController
{
    private TestEntities db = new TestEntities();

    [AcceptVerbs("GET")]
    public IHttpActionResult FirstAPI()
    {
        var myQuery = (from p in db.Participants
                       select new
                            {
                                p.ID,
                                p.Name,
                                p.MemberType
                            });

        return Json(myQuery);
    }
}

Second example taking two parameters

public class DefaultController : ApiController
{
    private TestEntities db = new TestEntities();

    [AcceptVerbs("GET")]
    public IHttpActionResult SecondAPI(int id, string name)
    {
        var myQuery = (from p in db.Participants
                       where p.ID == id && p.Name == name
                       select new
                            {
                                p.ID,
                                p.Name,
                                p.MemberType
                            });

        return Json(myQuery);
    }
}
2
  • Testing the client should use a mock that returns the JSON. Commented Aug 10, 2015 at 12:40
  • In this scenario, it may be a better idea to take a deeper look at your architecture. By moving this data access logic out of your WebApi Controller and into a service layer, you can then unit test those services. Your WebApi Controller is only exposing those calls to the client, and to test that, you would more or less test the HTTPStatusCode you get back. Commented Aug 10, 2015 at 12:59

2 Answers 2

1

You'd unit test it the same way you unit test anything... Invoke it and examine the results. In this case the result is of type HttpActionResult, which appears to have only one operation on it.

So your test will likely need to also invoke that operation, probably awaiting it since it's async, and examine the results of that which appear to be of type HttpResponseMessage.

That type has properties you can examine to validate the result of the operation you're testing. The most important property likely being Content, which contains the contents of the response. Your test will basically read those contents and validate them against an expected result.


The bigger problem here isn't actually validating the result, that's easy once you peer into the returned value as described above. The real problem with your unit test is this:

private TestEntities db = new TestEntities();

Your controller is tightly coupled to a dependency. Unless you have proper mocking set up within that dependency which isn't shown here, then your unit test will also be tightly coupled to that dependency.

Abstracting that dependency behind an interface and using dependency injection to de-couple your controller is highly recommended. That way your unit tests can supply a mock dependency with known, predictable behavior.

Sign up to request clarification or add additional context in comments.

2 Comments

OK, this just leads to a separate question. Can you point me somewhere to learn about abstracting that dependency behind an interface? I don't know if I need to open a separate question and solve that first before getting an answer to this one.
@madvora: There's a lot to cover with dependency injection. At a high level I actually have a presentation which conceptually covers it and provides examples: youtu.be/j6Le6YJH5o8 It's a bit dated, but should get you started. For considerably more in-depth expertise, I recommend just about anything written by Mark Seemann (among many others) on the subject: blog.ploeh.dk Essentially you have an answer to this question already, it's just that your tests are going to run into another problem with that coupling.
0

the code bellow run verry good for me :

var result = controller.Test(expectedArg) as JsonResult<MyClass>;

Assert.AreEqual(expectedResult, result.Content);

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.