In this article, let's learn about how to unit test
WebAPI in ASP.NET Core.
Table of Contents
- Why Unit Testing?
- What is a Controller?
- Unit Testing Controller
- Verifying Action Result
- Verifying Model Type
- Verifying Model Content
- Combining All Together
In this article, we will focus on unit testing
thick controllers, which are controllers that contain behavior suitable for
testing. While it's ideal to start with thin controllers, it's not always possible, especially when working with existing projects or teams that have different
design decisions. Writing pragmatic unit tests for thick controllers can greatly improve the application's reliability.
Why Unit Testing ?
Unit testing allows developers to
verify the behavior and logic of individual units of code in isolation.
By writing tests, you can ensure that your code functions correctly and remains reliable even after making changes or adding new features. Unit tests help catch
bugs early in the development process and provide confidence in the correctness of the code.
Note: If you have not done so already, I recommend you read the article on Implementing TDD in C# .Net.
What is a Controller ?
When it comes to testing
API controllers in ASP.NET Core, it's important to consider the
within the controllers. Controllers can be categorized as
thin. Thick controllers
contain logic and behavior that can be tested, such as
model state checks, database calls, mapping code, and conditional code.
On the other hand, thin controllers delegate the implementation of behavior to other components and typically
don't require unit testing.
Unit Testing Controller
To test API controllers in ASP.NET Core, it's crucial to isolate the controller's behavior from
external dependencies, such as model binding,
filters, and routing. Unit testing should focus on testing the controller's behavior itself, avoiding testing the ASP.NET Core framework.
Veriyfing Action Result
One aspect of testing API controllers is verifying the type of
ActionResult returned from a specific action. In many cases,
ActionResult<T> is used as the
return type, allowing for flexibility in returning
different types of
action results. To test the
ActionResult type, you can
assert that the returned
result is of the expected type, such as
Here's an example of testing the type of ActionResult returned from the
Code Sample - WebAPI Controller Action Result Test
Veriyfing Model Type
Another important aspect of testing API controllers is verifying the expected
model type returned by the action. The model
type is the
generic type parameter of the
ActionResult<T>. You can use the
Assert.IsAssignableFrom method to check if the returned model is assignable to the expected type.
For example, let's verify that the returned model from the
GetBlogs action is of type
Code Sample - WebAPI Controller Model Type Test
Veriyfing Model Content
Finally, we're going to verify whether the returned
DTO, in our case an
is correctly constructed by the action. We expect it to contain as many objects as were inputted, and in our case, we input three blogs. So what we want to test is
that we end up with three blog DTOs.
GetBlogs_GetActionMustReturnNumberOfInputtedBlogs. There is, again, nothing to arrange. To act, we
GetBlogs method again. And to assert, we first need to get a hold of the action result. We know how to do that by
now, as it's the same as what we did in the two previous demos. Once we've got that action result, we can cast the result of the action result to an
OkObjectResult and get the
Value property. Once we have that value, we can cast it to an
Code Sample - WebAPI Controller Model Content Test
Combining All Together
So far we focused on testing individual aspects of the controller's behavior. However, it is often useful to combine multiple asserts related to the same action in one unit test. This not only makes the test code more concise but also provides a clearer overview of the expected behavior.
To combine the asserts and fix the
null reference issues, we can make use of the
type's pattern matching capabilities. This allows us to simplify the code and handle
null values more effectively.
Let's update our test to incorporate these improvements:
Code Sample - WebAPI Controller Complete Test
In this article, we explored the process of
unit testing controllers in ASP.NET Core. We discussed the importance of unit
testing and when it is suitable to test API controllers. We focused on testing the
behavior of the controllers and provided
verifying ActionResult types, model types, and model content using C#.
Unit testing controllers allows us to ensure that the expected behavior is correctly implemented and provides valuable feedback on the reliability of our application. By isolating the tests and using mocks or framework techniques, we can focus solely on testing our code.