Unit testing, statics and factories

I am implementing a model in Java that requires iterating over a collection and going through several stages of identification, it includes loops, loops, etc. This is what I want to test on a fine-grained level so that I am sure that it was executed correctly.

I used it as an opportunity to start unit testing, as this is what I find useful for my code. Since then I have been reading forest books to speed up with JUnit and unit testing.

Basically my question boils down to two conflicting tips that I got:

1) The statics of evil. Do not touch the static. Do not also verify your identity; you probably want a class there.
2) Use factories to create to allow dependency injection using parameters - potentially allowing layouts and stubs to be used for isolation.

In my example, I want to perform a row-wise operation:

double height = 223.42; // this was set iterating over a collection of doubles //blah HeightBounds b = HeightBounds.getHeightBounds(height); //more blah 

I did this to avoid creating something that would become a very long and complex block of code that I can only verify in full. This way, I have publicly accessible objects that I can check to ensure that the system components are running correctly.

Common sense tells me that there is nothing wrong with static factories, and that they are easy to check, but am I missing something dazzlingly obvious, given that I am studying test design?

thanks

+6
source share
5 answers

The factory static class introduces a relationship between your class and the HeightBounds class. this can make your class difficult to test if, for example, HeightBounds disconnects and looks for information in the database, or reads from a web service, etc. etc.

If instead you IHeightBounds implementation into your class, then you can mock it so you can check what happens when your class dependencies do certain things.

For example, what if HeightBounds throws an exception? or returns null? Or do you want to check when a specific HeightBound ? With an interface, it’s easy to mock this behavior with a static factory, it's harder because you produce data to create the desired results in the class.

You can still only have one HeightBounds implementation, and you can test it separately, but you can test your method above without even having a real implementation.

I would probably have an IHeightBoundFactory interface and IHeightBoundFactory implementation into the class.

As for testing privates, as a rule, you do not want this. You want to experience one of two things, either that the results are what you expected, or that interactions are what you expected.

If you have a method called Add and a method called GetAll , then you can test it when you call Add and then call GetAll , you return the one you added. you don’t care how it is implemented, just the way it works. this is testing the results. Typically, in this situation, you want to create a mockup of objects that return data. This seems to be your situation.

If, when you call Add you expect that what is being added is being registered, then you want to test the interaction with the registration dependency, so you add the dependency on mock and verify that the interaction with this class happened when you called Add . Typically, in this situation, you want to create a mock of objects with established expectations and make sure that these expectations are met. It does not seem to be necessary in the situation described above.

+3
source

The statics of evil. Do not touch the static.

"static" here probably means Singletons, that is, a global state. It is really difficult to use in unit tests and can introduce many subtle problems, so it's best to avoid them altogether. However, static members (fields, methods, or inner classes) are not generally a problem in themselves.

Do not also verify your identity; you probably want a class there.

This is generally true, if you feel the need to test a private method, it is a sign that your API is not good enough, and the encompassing class might try to do too much. Often you can identify some cohesive group of features that is best extracted into a separate class. This improves your design and, in turn, simplifies unit testing.

+2
source

The problem with static factories is that you cannot replace factories (and sometimes objects created by factories) with mocks. “This is one of the reasons IOC containers are so useful.”

+2
source

Static methods basically kill unit testing.

One of the main ideas when you want to use unit test is the ability to isolate different parts of your code. You usually do this by mocking objects for your environment. You cannot connect anything if you use static methods. Moreover, the use of static methods hides the dependencies between objects.

In the last paragraph, you say you want to learn about test design. If you write your tests after you have written the code, your tests do not actually control anything. Write your tests first.

For private methods, you should usually have a full test coverage of public methods that use these private methods, so you should cover them anyway. If you have a really complicated private method that you want to test (you shouldn't), just use reflection to make it available. I would rather break encapsulation than untested code.

Misko Hevery has a very good post on this topic.

+1
source

Static methods are not evil per se. Look at the JDK for how many of them are. Static methods should also be checked per unit, so if you have any functions, check them out.

So, it’s not that static methods kill unit testing.

But if you are only statically writing less code in unit tests, then this is the wrong way, as others claim you should use your objects better using your regular API, because that is what you want to test.

And a complete ACK for writing tests first - it will also help you develop a better API, cut your classes correctly.

0
source

Source: https://habr.com/ru/post/885737/


All Articles