DEV Community

Cover image for Hands of the privates
Michiel Hendriks
Michiel Hendriks

Posted on

Hands of the privates

I am not a fan of private visibility. It prevents extensibility, but more importantly, it prevents unit testing.

You shouldn't unit test private methods. I hear you say. But why not?

It is time for a bad analogy. Lets say I have I have this FoodFactory and I have a great hamburger recipe. So I would have the method

public Hamburger createHambuger() {
    // ...
}

We probably all agree that this method should not contain every single step in creating a hamburger, but you would probably do something like this.

public Hamburger createHambuger() {
    Stack parts = new Stack();
    parts.add(createBottomBun());
    parts.add(getLettuce());
    parts.add(getTomatoSlice(2));
    parts.add(createPatty());
    // ...
    parts.add(createTopBun());
    return assembleHamburger(parts);
}

At some point in time we start getting complaints that the top bun does not have sesame seeds on top. Which is weird, because it is part of the top bun. After some extensive debugging and eating a lot of hamburgers we find out that sometimes createTopBun() returns the bun upside down.

This would be an easy fix. We just create a unit test to assert createTopBun() returns the bun right side up, and ... wait! Our awesome hamburger is a top-secret recipe, so all our steps should be private methods. The only way to test if the top bun is right side up I need to create a full hamburger and then dissect the result. Which would also mean my test setup needs to also take care of having the inventory to create the patty, etc. All I wanted was to verify the top bun.

With the exception for security related parts, why should I make things private instead of protected?
And why should I not test private methods?

Top comments (1)

Collapse
 
aleksikauppila profile image
Aleksi Kauppila

Maybe the top bun is a missing abstraction that you can test using its public interface.

class TopBun {
   hasSeedsOnTop(): bool;
   flip(): void;
}

Private interface is a way for you to protect the implementation details from being exposed. When all dependencies to those private methods come from inside the object you'll have the freedom to make changes which don't affect the clients of that object. We want to avoid coupling to small details.