Should I Never Use Static Methods and Classes and Singletones Following the Driven Development Testing Paradigm

I read that static methods, static classes, and singletones are evil when you try to implement unit testing in your project. Following the TDD paradigm, should I just forget that they ever existed and never used them again, or is it normal to use them sometimes?

+17
source share
4 answers

Never say never - static classes and methods have their place in the toolbar.

However, if the class you are trying to isolate and test (the subject under testing or SUT) depends on the static class or method, you cannot write a test that isolates the SUT from this static dependency - when your test code works, it’s all will use a static call equally. Sometimes it's fine, but sometimes you want to create an isolated test that checks ONLY the logic of your SUT without any dependencies (usually through ridicule or similar methods).

In general, I personally use static classes and methods relatively sparingly.

Due to the nature of the implementation of Singletons, they present a similar problem for isolating SUTs for unit testing. In addition, the concept of single-player GOF is considered bad practice by a certain percentage of software developers. I agree with this attitude, but there is hardly a consensus on this issue. A quick google search will probably give you a pretty good idea of ​​the pros and cons of the Singleton GOF template.

+10
source
  • Should you forget that they ever existed? No.
  • Do you need to make sure that they are included in your code in such a way that they are transparent to the functionality of the class? Yes.

To explain this last part further, instead of trying to get the value from singleton code inside your code, try initializing the value in the constructor argument. If your constructor is too large, create a factory method to create so you can test your class without using a singleton. If this turns out to be problematic, or your singleton has a mutable state (I would be afraid of this, but, hey, this is me), then try it so that your singleton is as easily included in your testing as possible.

You do not need to create the entire configuration file to check the class method, which calculates the standard deviation of the stock quotes block over a 4-hour period. This is too much work. But if your singleton is written in such a way that you can fill it with data, and another class should be responsible for reading in the configuration file and filling this data, then you have taken great steps forward.

Regarding static methods, I would say that they are the most easily verifiable methods that you could write based on the condition that you do not need to worry about the global state. The static equivalents y = f(x) , which seem simplified, but underlie the fact that no local state transitions can change the invariant, which for a given x you always get the same y .

+3
source

As with any software development practice, there is never a single final solution to any situation. Therefore, you should never exclude static methods, static classes, and singletones. The purpose of TDD is to make your life easier, and you will notice that as you work more with TDD, your code will be modular, which means that even if you use static methods (... etc.) Your code will continue to be verified.

Rule I like living: use whatever you like while your code is easy to read and your design is elegant. How you achieve these 2 is up to you. If you can still deliver an elegant code, you can use GOTO.

+2
source

I read that static methods are ... evil when you try to implement unit testing

I have never read this. Could you provide a link? And I would dispute this. I use unit test and static methods (functions) all the time and without problems.


Edited

Thanks for the link to Static methods - this is mortality for testing : This article is garbage.

The main problem with static methods is the procedural code. I have no idea how unit test code is.

This means that the author does not know much about unit testing. Of course, you can unit test the procedural code.

During creation, I associate dependencies with mocks / friendlies, which replace real dependencies.

This is a key mistake: the idea that unit testing requires mock objects. Is not. In any case, you can pass the layout of the objects as arguments to the static method you are testing: no constructor is needed to inject dependencies. For more information, see the accepted answer to the question "Static methods: when and when not."

if the static method calls another static method, it is not possible to override the dependency of the called method.

True, but it does not matter. If static method A calls static method B, then this is a detail of the implementation of method A. Therefore, you do not have a business trying to intercept call B. Just treat A as a unit.

Suppose your application has nothing but static methods

The argument of Solomon. Obviously, in the context of modern unit testing, we are talking about the OO program with only some static methods.

-1
source

All Articles