tomasz-mer
tomasz-mer

Reputation: 3930

How to test private classes in junit whitout changing accessible to true

I have example to ilustrate my problem:

package com.example;

public class ExamplePublicClass {

    public void doSomething() {
        // a lot of code
        String message = new ExamplePublicClass.MessageBuilder().withName("someName").build();
        // a lot of code
    }

    private static class MessageBuilder {

        private String name;

        public MessageBuilder withName(String name) {
            this.name = name;
            return this;
        }

        public String build() {
            return this.name + 1;
        }
    }
}

doSomething() method doing a lot o things and there is a lot o legacy code but it works and I don't want to touch her.

Only what I want to do is a change a builder to creating a log message and write a test for him. The problem is the fact that MessageBuilder is a private class and is doesn't make sense to change it to public.In additonal I don't want to changing visibility through reflection.

I added a class for test in the same package

package com.example;

import org.junit.Test;

public class MessageBuilderTest {

    @Test
    public void testMessageBuilder() {
        String s = MessageBuilder..
    }

}

but I don't have access to this private class :(

Working code is located in

src/main/java

and test code is located

src/test/java

What do you thing? Should I change project structure to

src |/main/java |/test/java

?

Or exist better solution?

Best Regards T

Upvotes: 2

Views: 2061

Answers (1)

Konstantin Yovkov
Konstantin Yovkov

Reputation: 62884

I've always considered modifying access via Reflection as a bad practice, which is useful for nothing but understanding that there is something wrong with the design. :-)

In general, a unit test is intended to test the public (or actually, the non-private) interface of a class. All private methods are implementation detail that you would not expect to test explicitly.

When you have private methods in a class and you want to Unit-test them, this is considered as a sign for a code smell, because the class can be simplified/modified so that the private units are unit-testable.

You can do one of these:

  • refactor the nested private static class to a top-level one and mark it as package-private accessible.
  • provide a public (or, at least, non-private) access to the private units that you want to test.

You can also take a look on this thread, where the topic is discussed more extensively.

Upvotes: 1

Related Questions