Look at it from a different perspective (Test-Driven Development): easy-to-test code is easy to use. Writing unit tests, you are actually testing the "open interface" of your code. If this is difficult to verify, because you have some dependencies that make work difficult. Do you really need a containment relationship, or do associative relationships make more sense?
In your case, I personally think that it would be more testable to pass Engine in the constructor, so I would reorganize the constructor, as in your proposal # 1. You can test the Engine in one test suite and provide the Engine layout for testing the car in another test suite . Testing is now easy, which means the interface is easy to use. It's good.
Now think about how to use this implementation in a real project. You must create the CarFactory class, and the factory will create the engine and place it in the car before it is delivered. (Also notice how this ends with a more thorough simulation of the real world of cars and engines and factories, but I'm distracted.)
So the answer to TDD would be to reorganize the code to take the Engine pointer to the constructor.
source share