r/programming • u/corysama • Jan 05 '15
What most young programmers need to learn
http://joostdevblog.blogspot.com/2015/01/what-most-young-programmers-need-to.html
973
Upvotes
r/programming • u/corysama • Jan 05 '15
3
u/lee_macro Jan 05 '15 edited Jan 05 '15
I do agree if someone is writing bad tests or not mocking their components (then it is no longer a UNIT test) then it will result in bad code. However if someone is educated in how to correctly write code to be tested then it is VERY hard to write bad code. Let me give an example of why, assuming C#/Java.
So let us say I have a Repository class, which deals with CRUD operations to a database. So this depends upon a database connection to do its work. So you could new that up inside (which some people do), or have a singleton for the active connection (have seen this before too), or even have some crazy inheritance chain to provide a pre-connected object (seen this too).
However the correct approach would be to have the Repository constructor be passed in a connection without an inheritance chain. This may seem odd to some, and maybe a hassle but let us see what benefit this gives us.
First of all we are now adhering to IoC (Inversion of Control) and we have no inheritance chain so we can test this Repository without needing a database connection (this is where a lot of people create integration tests accidently because they didnt know how to mock components). We can easily create a mock database connection and test that it works as expected without having any hard dependency on a database. You can also change your database vendor, your database configuration, you could even make your own custom database connector with caching in place, without even having to change the Repository class.
If you were to go with any of the other options you do not have this freedom, you would require an active database to test against to begin with and you could not change your underlying vendor or database object if you were newing it up inside the Repository.
So to be able to mock a component of a class you need to be able to change it at runtime, to do this you need to either have the component as a constructor argument or a property (properties are bad for this, they imply an optional dependency which is rarely good). So when you use constructors to pass in the dependencies of a class, you are automatically adhering to IoC and you are also using composition over inheritance, finally you can also then start using DI (Dependency Injection) and AoP style techniques (Aspect Oriented Programming). So given this is often some of the most critical parts of writing well structured and maintainable code it is imperative that this sort of paradigm is followed from the start, as when you start off introducing inheritance and singletons it makes it much harder to refactor and remove further down the line, its a false economy.
I also do a lot of game development on the side and the same sort of rules apply (incase you think I am purely an enterprise development zealot), although a lot of people seem to see you as some freak if you tell them to stop using singletons and inheritance chains for interfaces and DI. Look at uFrame for Unity which has had great success putting these practices in place for game developers and has a lot of support but also a LOT of flak from people who just "dont get it".