Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it a bad practice to put JUnit test method into the tested class?

Tags:

java

junit

Consider a Java class with small library-style static methods.

Is it a bad practice to place JUnit test methods in the same class?

I see the following pros:

  • JUnit test as a self-documentation is right near the method code
  • Will be easy to move this code to another class or package

What are the contras, and why it is a general practice to always separate the test code?

An example:

import org.junit.*;

public class HtmlUtils {
    public static String normalizeBrs(String html) {
        return html.replaceAll("<br\\s*/?>", "<br/>");
    }

    @Test
    public void testNormalizeBrs() {
        Assert.assertEquals(normalizeBrs("hello <br /> world <br>"), "hello <br/> world <br/>");
    }
}
like image 637
Mikhail Dvorkin Avatar asked Jan 05 '23 12:01

Mikhail Dvorkin


2 Answers

( Is it a bad practice to put JUnit test method into the tested class? )

Absolutely.

The key reason here: single responsibility principle. A class, a method, any thing in programming should support/provide exactly one responsibility.

The core responsibility of your production code is to fulfill its "production purpose".

In other words: business logic is business logic. Nothing else.

Anything that doesn't belong in that bucket ... goes somewhere else.

Testing is such a "thing", aspect, responsibility, however you name it.

The more typical approach is to even have different projects for production and test code.

When your production class is x.y.Z ... then the test class would be x.y.ZTest; but although they reside in the same package, you would normally place them into different source location folders.

And beyond that: refactoring for Java is can be seen as "solved problem" in 2017. Moving around methods into different classes, or changing package names is so easy today that you (absolutely) do not need to worry about that. (if refactoring looks so dangerous to you, that you consider polluting your production code with test code, then well: learn how to use modern day tools)

Also, if you put your test methods inside of the tested class, you will probably end up testing the internal implementation. This is not what you are supposed to test. You should test against the class API; your tests should be independent of the internal implementation.

like image 161
GhostCat Avatar answered Jan 28 '23 18:01

GhostCat


you may not notice any difference if your package is small.

But imagine you have a package containing 1000s of classes then having 10s of thousands of methods. meaning 10s of thousands of tests.

so what will happen if having all codes + tests together?

for something like that you may end up loading memory with garbage that will never actually serve any purpose.

This is why general practice always encourages you to have them separated. by following this for smaller package you are actually training yourself for bigger projects too.

like image 28
nafas Avatar answered Jan 28 '23 19:01

nafas