Is isInUnitTests () a code smell?
Yes, in the long run, you have many ways to avoid combining code with unit tests. There is no good reason to have something like this.
If so, how can I still apply those unit tests that do not reach external dependencies?
Your tests should only check the unit of code and create a layout or stub for external dependencies.
Your code seems to be Java in which there are a lot of mature frames. Learn a little about existing ones and choose the one you like best.
EDIT
how can I prevent unit test from creating a real instance of HTTPRequest without putting the check in the constructor / factory method that creates it
It is supposed to use the dependency injector to resolve dependencies between instances, so you will not need to use if for testing if you are testing or not, because you enter full functional dependencies on your "real" code, and you enter a layout or stubs on your test.
Take a more serious example, for example, a credit card charger (an example of classical testing) - it will be a very poor design, if even the test code could access the real charger without causing a flood of exceptions, I do not think that this is enough in in such a case, to trust the developer will always do the right thing
Again, you must introduce external dependencies as a credit card charger, so when you test, you enter a fake one. If some developer does not know this, I think that the first thing your company needs is training for this developer and several paired programs to guide the process.
In any case, I will get your thought and let you tell you about a similar situation that I experienced.
After some processing, several letters were sent. These letters were not sent to any environment other than the living, otherwise it would be a big problem.
Before I started working on this application, this happened several times when the developers βforgotβ this rule and emails were sent to test environments, which caused a lot of problems. This is not a good strategy that depends on human memory to avoid such a problem.
What we did to avoid repeating this event by adding a configuration setting to indicate whether to send real emails or not. The problem was wider than performing any action or not on unit tests, as you can see.
Nothing will replace the link, although the developer may have set the wrong value for this parameter in his development environment. You are never 100% safe.
Shortly speaking:
- The first line of defense is communication and training.
- The second line of defense should be dependent injection.
- If you feel that this is not enough, you can add a third line of defense: configuration settings to avoid executing real logic in a test / development environment. There is nothing wrong with that. But please do not call it
IsInUnitTest , because the problem is wider than this (you also want to avoid this logic, which must be executed on the developer's machine)