In order to test a instance method you need to instantiate the object, so do not put any business logic code into the constructor or static factory methods.
Move the dependencies to constructor parameters so that you do not need to care how they get instantiated. We can pass in a mocked dependency or a real object.
Having dependencies defined in constructor argumeters makes the API more clear.
That makes testing much more easier since mock all the dependencies.
Write many small tests for business logic and create a one happy path test that everything is wired together correctly.
In constructor we should be asking what we need but not creating it ourselves, should not create and use any Factories inside constructor/method code.
Ideally, you would have only field assignments in your constructor.
Tests about instantiating small pieces of your application.
You could use service locator (aka context or registry) to create an object for you instead of creating it yourself. However, in order to get the mocked object you would have to override the service locator methods which can be hard sometimes (looking into source code etc…)
When there are multiples constructor parameters and you want to test behavior based on the first paramter, then you can make the other null in tests, meaning that do not take part in the test.
Law of demeter: only ask for the objects that you need directly, don’t use intermediate object that will the get what you need for you.
If your child object needs a new parameter in its constructor, it should not be added to the as parameter parent constructor. Parent object need only to know about the child, not the children dependencies. Otherwise the parent would violate the law of demeter adding as its constuctor parameter something he doesn’t directly needs.
One factory plus a couple of break down factories per object lifetime.
As a parameter of a constructor put objects of longer or the same lifetime. Put objects of a shorter lifecycle as method parameters.
For external api the will be used by other people, put validation logic into constructor. For internal api it is not suggested to use these checks since it make testing harder (need to meet extra preconditions before you really can start testing) – in this case tests are better than runtime precondition / check.
For production code you should return non null objects (not to get NPE). For test code passing null as a parameter makes it clear that this parameter is not important for the test.
For production code do not call ‘new’ operator (do not instantiate objects directly) in constructor so that somebody can pass in you a mock in the constructor argument. You should ask for what you want instead creating it by yourself.
The ‘new’ operator should be used only in tests and factories. Exception are the leaves of the application graph, there is nothing behind them, e.g.: value objects (e.g. User) or collections (new HashMap).
Law of demeter: only ask for the thinks that you need directly, you shouldn’t know about the objects you don’t need.
Objects should be divided into two categories:
1) business logic objects that do the logic in your application (here are most of bugs so you should make them easy to instantiate and to test)
2) Pile of factories, the ‘new’ operators, builders etc …
Then you can test objects instantiation and business logic separately, in isolation.