Test a method that is using another static method

This is the third and final part of a series that we started under the title “What should be considered for unit-testing”. In this article, we will take a look at how we can test a method that is using another static method.

Probably you are saying. Oh yeah, I know this dude, and believe me, This is such a pain… and I have to say, that I completely feel the same! In my opinion, static methods are generally misunderstood. Let’s just avoid an unnecessary headache by describing why do I think this way and establish a simple rule:

We use almost all the time static keywordjust for the static class properties and we avoid defining static methods.

You ask me why? honestly, I would rather hear your reason for defining static methods!

Just for the sake of testing, anybody who ever tried to write a unit test for a method, which uses another static method within itself, knows that you can’t mock it! and that is bad! real bad!

I know, you fancy developers might say, no it’s not completely true, because you can use power mock or superpower mock or … but it’s more like you intentionally cut yourself just because you know a fancy doctor who can stitch it for you!

Anyway, I assume that I could make my point against writing static methods. Now let’s say we are in a situation where we have to use a static method in our class and don’t have the authority to change that. In this case, there are a couple of ways to get around it. My favorite one is the most simple yet powerful one. I would wrap that single static method into an interface and inject the interface into the target class. This way I can finally mock the interface in my unit test!

public class Sample {
    public String isPositive(int a, int b) {
        return Calculator.add(a, b) > 0 ? "positive" : "negative";
    }

    public static class Calculator {
        public static int add(int a, int b) {return a + b;}
    }
}

when you want to test the positive method functionality you may want to mock the static add method and by now you should know it is going to be a simple task. But here is a good workaround:

public class Sample {

    CalculatorWrapper calculatorService;

    public Sample(CalculatorWrapper calculatorService) {
        this.calculatorService = calculatorService;
    }

    public String isPositive(int a, int b) {
        return calculatorService.add(a, b) > 0 ? "positive" : "negative";
    }

    class CalculatorWrapperImpl implements CalculatorWrapper {
        @Override
        public int add(int a, int b) {return Calculator.add(a, b);}
    }
    interface CalculatorWrapper {
        int add(int a, int b);
    }
    
    static class Calculator {
        public static int add(int a, int b) {return a + b;}
    }
}

You can see, that to get around it we had to add lots of unnecessary code into the production code, which is definitely not a decent thing. That is another good reason why we should avoid writing static methods in the first place.