I have a class that would highly benefit from Unit tests, but few methods that call remote web server must be replaced by something delivering mock results. The probable solutions I see are:
- Test the derived class that overrides problematic methods (no test-related code in production, just methods must be non-private and non final).
- Extract problematic methods into separate component.
The second case requires to add this component somehow during both tests and production runs, and may have at least the following solutions:
- Have protected field that can be directly assigned during the setup of the test, replacing the component there. Somewhat breaks OOP concepts.
- Have the setter to set the component. It is still not the best API as this component cannot be suddenly replaced after the main object becomes active with its functions. It would be a method with the limited time window to call.
- Have the constructor that takes either web-interacting implementation or mock. This makes the API somewhat strange (always construct and pass the same object).
- Have the second constructor for testing only that takes a mock, production constructor calls
this
(..) with the production instance pre-constructed. - Have something like naming service that resolves the component (looks like lots of work to create and maintain it, if just for testing support, singleton pattern).
- Use dependency injection framework (if the project is smaller, also looks like lots of overhead).
Which of these proposed solutions are "theoretically correct"? Or maybe some other solutions are more correct?