1

How can I create unit test for testAble() method and mock the behavior of something() method?

public class MyClass {
    public static String something() {
        return "Hello";
    }

    public static String testAble() {
        if (something().equals("Hello")) {
            return "Wow";
        }
        return "LoL";
    }
}

I was trying to do it using Mockito but I came to know that we can't mock static using Mockito.

Gul Ahmed
  • 13
  • 1
  • 3
  • It's an implementation detail, you shouldn't be required to test it. Also, your method is always returning "Wow", never anything else (because the static call is static, even and especially at runtime) – knittl Jun 30 '23 at 11:06

1 Answers1

0

Since Mockito version 3.4.0 it's possible to mock static methods when using mockito-inline dependency - see: Mockito docs or you can read more here.

In your case it would look like this:

@Test
void notHelloTest() {
    try (var mocked = Mockito.mockStatic(MyClass.class, CALLS_REAL_METHODS)) {
        mocked.when(MyClass::something)
              .thenReturn("not hello");

        var result = MyClass.testAble();

        assertEquals("LoL", result);
    }
}

@Test
void helloTest() {
    try (var mocked = Mockito.mockStatic(MyClass.class, CALLS_REAL_METHODS)) {
        mocked.when(MyClass::something)
              .thenReturn("Hello");

        var result = MyClass.testAble();

        assertEquals("Wow", result);
    }
}

Please note the CALLS_REAL_METHODS parameter (static import from org.mockito.Answers) passed to mockStatic method - it's required since we're testing the same class that we're mocking. Without it MyClass.testAble() returns null as we're not defining its behavior (and we want to test it, not mock it).

I've created a GitHub repository reproducing your question, where I've also added the tests above - they both pass.

Additional note: you could solve the problem by using non-static methods instead of static ones and injecting the instance of your class into another class (and inject a test double in tests). Dependency injection mechanisms make it easy for us.

You may also want to read about the try-with-resources block - static mocking works only within the try block and the static mock is closed when the block ends.

Jonasz
  • 1,617
  • 1
  • 13
  • 19
  • Amazing and thank you! What if method call we are mocking is private? – Gul Ahmed Jul 03 '23 at 02:28
  • It's not possible in Mockito. You should mock external dependencies of your class (other classes), the internals (e.g. private methods) should not be mocked as it's the part that should be actually tested. If the answer helped you, please remember to accept and upvote, thanks :) – Jonasz Jul 03 '23 at 06:34