Click here to Skip to main content
15,867,453 members
Articles / DevOps / Unit Testing

You Should Unit Test Your Controller, NOT!

Rate me:
Please Sign up or sign in to vote.
4.43/5 (12 votes)
28 Jul 2019CPOL3 min read 27.6K   13   13
One of the MVC mantras is that it allows unit testing your controllers. But, that doesn't mean you should. In my opinion, you should focus your unit testing valuable effort in more effective areas as the controller, if done right, doesn't require unit testing.

Unit Testing MVC

Unit testing per se is a controversial topic, what you should unit test is another controversial topic. The topic of this post started by a short conversation during a .NET London Group meeting back in 2010, I thought about it and then gave it more thoughts, I started using it in my projects, then now I have enough confidence to share my thoughts. Here is my opinion, if you agree or disagree, then please do comment.

Controllers Should Be Slim

You’ve heard this before: “Controllers shouldn’t be fat, controllers should contain minimal code”, it’s a mantra.

The S in SOLID stands for SRP. A controller should have one role, it is the communication layer between a model and a view. Even with this role, it is violating SRP, one could say maybe we need two classes to take the role of a controller or a controller per action method, but let’s not delve into that.

The controller, by role, is overloaded with responsibilities, adding more responsibilities to it is a design crime (maybe one should be penalized by losing some StackOverflow or CodeProject points :) ).

Why Do Controllers Get Fat?

I did blog earlier on how views become fat Three Steps to Get Fat-Razor MVC Views on Diet, some points are common and some are specific to controllers:

Explicit Validation of Data in the Action Method

Validation of your viewmodel data in your controller violates two principles:

  1. SRP Design Principle: You are attaching more responsibilities to the controller.
  2. Encapsulation OOP Principle: You will have to expose your data outside your viewmodel to allow another object, the controller, to validate it, while the object itself should be responsible for its own data.

ASP.NET MVC 4 has a good validation ecosystem that will help you in moving your validation code to where it belongs.

Mapping a Model to a Viewmodel

The mapping from a model to a viewmodel should not be done in the action method. My favorite solution is to use a CQRS type query pattern so I don’t have to do this boilerplate anywhere. Here is a good Introduction to CQRS.

Leaking Some Business Logic

This is not a place for any business logic. The controller should be calling a service, of a classical DDD implementation, or issuing a query or a command of CQRS.

HTTP-related Code in the Action Method

Having a special HTTP case that requires special handling should not be done here. Action filters might be the answer.

What Are You Unit Testing?!

Given the above and if your action methods have almost no code, then what are you unit testing? Do you want to test if you are returning the proper view or do you want to test if you have decorated your action method with the proper attributes? I wouldn’t, I usually have a deadline to hit and I am against boilerplate code.

If someone tells me their controller requires unit testing, I will ask, did you design your controller properly?

Conclusion

Unit testing is a means for providing higher quality software and not an aim per se. Having too many redundant unit tests will cause a future maintenance headache and will cost more project development time.

If an area/layer requires unit testing, then you should probably test it, but for other areas, more tests may be less quality.

Update - I told you not to unit test your controllers, by keeping them empty, here is one way to keep your controllers thin: Implementing a CQRS-based Architecture with MVC and Document DB.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
United Kingdom United Kingdom
Passionate about refining software practices, promoting self-motivated teams and orchestrating agile projects.
Lives in London, UK and works as a .NET architect consultant in the City.

Blog AdamTibi.net.

Comments and Discussions

 
PraiseCode Coverage Pin
Dong Xie29-Jul-19 1:31
Dong Xie29-Jul-19 1:31 
QuestionWhat about simple apps? Pin
morzel26-Jun-13 0:33
morzel26-Jun-13 0:33 
AnswerRe: What about simple apps? Pin
Adam Tibi26-Jun-13 5:27
professionalAdam Tibi26-Jun-13 5:27 
GeneralMy vote of 5 Pin
Enrique Albert24-Jun-13 0:38
Enrique Albert24-Jun-13 0:38 
GeneralMy vote of 5 Pin
saguptamca17-Jun-13 22:44
professionalsaguptamca17-Jun-13 22:44 
GeneralMy vote of 3 Pin
Paul Tait17-Jun-13 0:19
Paul Tait17-Jun-13 0:19 
GeneralRe: My vote of 3 Pin
Adam Tibi17-Jun-13 0:31
professionalAdam Tibi17-Jun-13 0:31 
The reason I have no code is that I am saying do not unit test, therefore there is no unit test code Smile | :)
Make it simple, as simple as possible, but not simpler.

GeneralRe: My vote of 3 Pin
Paul Tait17-Jun-13 2:08
Paul Tait17-Jun-13 2:08 
GeneralRe: My vote of 3 Pin
Adam Tibi17-Jun-13 2:39
professionalAdam Tibi17-Jun-13 2:39 
GeneralRe: My vote of 3 Pin
Paul Tait3-Sep-19 21:01
Paul Tait3-Sep-19 21:01 
GeneralRe: My vote of 3 Pin
Adam Tibi30-Oct-19 2:45
professionalAdam Tibi30-Oct-19 2:45 
GeneralRe: My vote of 3 Pin
Adam Tibi22-Jun-13 1:27
professionalAdam Tibi22-Jun-13 1:27 
GeneralRe: My vote of 3 Pin
raddevus29-Jul-19 7:24
mvaraddevus29-Jul-19 7:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.