RESTFul APIController Unit Testing Best Practices

Today in this article, we will learn RESTful API Unit Testing – Best Practices.

The recent popularity of frameworks like RESTful services (WebAPI) is getting huge traction.

We must develop robust microservices with a clear focus on TDD ( Test-driven Development) by following basic Unit Testing, Integration Testing, and Functional testing as a whole.

Today in this article, we will cover below aspects,

While performing Unit testing there is always confusion in developers on what is scoped under the Unit Testing.

Today we shall see basic guidelines for WebAPI Controller Unit testing.

These guidelines revolve more around RESTFul services built using ASP.NET Core WebAPI project templates.

We shall discuss below things that are important from Controller level Unit Testing.

  • Verify Inputs
  • Verify Controller method Response
  • Verify HTTP Status Code(static check only, don’t get confused by the Integration test)
  • Verify Mocked method invocation if any
  • Verify Extension method invocation if any
  • Verify Annotation/Attribute if any

Here I am using the XUnit test framework but you can use a test framework of your choice.

A Controller is a Class!

Before we begin writing unit test cases for the controller, the first thing you should understand is that “Controller” is not special when it comes to Unit testing.

The controller is a class like any other class which has members like methods and properties etc.

In Unit Testing, we create an instance of the target class call its method for various inputs, and assert the result as per expectation.

//Arrange
           BooksController service = new BooksController(mockBookClient.Object);

//Act
            var result = await service.GetAsync(document.Id) as ObjectResult;
            var actualtResult = result.Value;

The only thing we do a bit differently in Controller unit testing is that of the REST response assertion additionally.

All you need to do is create an instance of the Controller class and invoke all its methods and verify I/O

Verify HTTP Status Code

Controller methods always return HTTP responses along with resource details by following the REST principles which should include Model state verification and HTTP Status Code.

Controller methods should be unit tested using assert for REST HTTP Status code.

Use the HttpStatusCode enum type to Assert the responses.

Example 1

Assert.Equal(HttpStatusCode.OK, (HttpStatusCode)result.StatusCode);

Example 2

 Assert.IsType<OkObjectResult>(result);

Above, either way, the Unit test makes our API robust and validates the implementation of the REST principle following HTTP verbs correctly.

Each Controller method should be asserted for all possible types of HTTP Status codes like,

Commonly assertions should include

These assertions will ensure that the Controller method produces proper results.

Reference: Asynchronous Method Unit Testing in .NET Core

Verify API Response – Static Checking

If the controller method is returning resources, such resources should be validated for their structure.

The below example has the response cast to the actual type i.e. Book to very the schema of returned responses.

//Act
           var result = await service.GetAsync(document.Id) as ObjectResult;
           var actualtResult = result.Value;
//Assert
            Assert.Equal(document.Author, ((Book)actualtResult).Author);
            Assert.Equal(document.BookName, ((Book)actualtResult).BookName);
            Assert.Equal(document.Id, ((Book)actualtResult).Id);

  • This will ensure that the code follows a contract properly when the consumer consumes your API.
  • This schema assertion will red flag the code while development if there are any breaking changes.

Reference: Asynchronous Method Unit Testing in .NET Core

Verify Mocked/Extension invocation

Always assert if mocked methods are invoked at least once. The mocked method is the dependency that is avoided intentionally to concentrate only on the unit of work in isolation.

Example:

Verifying for the above code if the GetBooksAsync method which is a dependency (mocked) is called once.

mockBookClient.Verify(c => c.GetBookAsync(It.IsAny<string>()), Times.Once);

Reference: Unit Testing Extension Method in ASP.NET Core

Verify Business exception

API responses are critical as there will be consumers using the same as criteria. One can cross-check if business exception messages are raised appropriately.

Most business exceptions will be based on the HTTP status code giving an indication of the resource state. This static check on the return type will make your code robust.

Reference: Asynchronous Method Unit Testing in .NET Core

Verify Attributes for the Controller method

There is absolutely no problem in adding more test cases including Custom attribute validation or [Authorize] attribute validation within the Unit Test cases.

References: Unit Testing Authorize Attribute ASP.NET Core

Mark your Test method as Async

As good practice mark your Unit test method as async if Controller methods are Asynchronous in nature.

blank

Your test cases are a state machine. Your test suite in any form will protect your code from anomalies and breaking changes apart from making new code robust and compatible with existing code.

-TheCodebuzz

On the good side of unit test cases, you need not have wait for the integration of different modules ( require in Integration test and real API Test) helping in real-time identifying the breaking changes.

Most Unit test cases run as you type your code, hence it is easy to be tested or identify breaking changes.

We are in the world of XP practices and Continuous Development, Continuous review, and Continuous deployment is the way to go.

Do you have any better suggestions to test the Controller method? Please sound off in your comments below.

That’s all, Happy Coding!

Summary

Today in this article, we learned helpful guidelines on Controller or RESTFul API Unit testing. It’s important to unit-test all possible scenarios for a Controller to make our API robust.



Please bookmark this page and share it with your friends. Please Subscribe to the blog to receive notifications on freshly published(2024) best practices and guidelines for software design and development.