Unit Testing – Is Using ‘New’ in the Constructor Always Bad?

constructorsunit testing

I have read that using "new" in a constructor (for any other objects than simple value ones) is bad practice as it makes unit testing impossible (as then those collaborators needs to be created too and cannot be mocked).
As I am not really experienced in unit testing, I am trying to gather some rules that I will learn first.
Also, is this is a rule that is generally valid, regardless of the language used?

Best Answer

There are always exceptions, and I take issue with the 'always' in the title, but yes, this guideline is generally valid, and also applies outside of the constructor as well.

Using new in a constructor violates the D in SOLID (dependency inversion principle). It makes your code hard to test because unit testing is all about isolation; it is hard to isolate class if it has concrete references.

It is not just about unit testing though. What if I want to point a repository to two different databases at once? The ability to pass in my own context allows me to instantiate two different repositories pointing to different locations.

Not using new in the constructor makes your code more flexible. This also applies to languages that may use constructs other than new for object initialization.

However, clearly, you need to use good judgment. There are plenty of times when it is fine to use new, or where it would be better not to, but you will not have negative consequences. At some point somewhere, new has to be called. Just be very careful about calling new inside a class that a lot of other classes depend on.

Doing something such as initializing an empty private collection in your constructor is fine, and injecting it would be absurd.

The more references a class has to it, the more careful you should be not to call new from within it.