mockito, how to mock a class which is a member of the container class

325 Views Asked by At

With mockito-inline how to test static function (with stubbing other static function), or mock/stub some internal depended class?

Here is the sample:

Having a class Util which internally depending on java.security.MessageDigest

package java.security;
public abstract class MessageDigest extends MessageDigestSpi
    ... ...
    public byte[] digest() {
       
        byte[] result = engineDigest();       
        return result;
    }
}

and the container class has a few static functions to be tested

public class Util {

    public static byte[] getStringDigest(@NonNull String text, @NonNull String algorithm, @NonNull String charSet) {
        if (text == null) {
            return null;
        }
        MessageDigest messageDigest;  //<== depend on 
        try {
            messageDigest = MessageDigest.getInstance(algorithm);
            messageDigest.update(text.getBytes(charSet));
        } catch (UnsupportedEncodingException | NoSuchAlgorithmException e) {
            return null;
        }

        return messageDigest.digest();
    }

    public static String generateId(@NonNull String s) {
        byte[] sha1Byte = getStringDigest(s, "SHA-1", "UTF-8");
        if (sha1Byte == null) {
            return s;
        }
        // otherwise build the id
        String id = buildId(sha1Byte);
        return id;
    }
}

would like to test the Utils.generateId(@NonNull String s) with stubbing getStringDigest() returning null, so that sometext is expected to return.

since it is static function so it was tested with powermock.

@Test
public test_util_1{
        PowerMockito.mockStatic(MessageDigest.class);
        String sometext = "sometext";
        PowerMockito.when(Util.getStringDigest(sometext, "SHA-1", "UTF-8")).thenReturn(null);
        assertEquals(sometext, Util.generateId(sometext));

}

with mock stub, when Util.getStringDigest() is called null is returned. It worked fine.

now the mockito-inline supports testing static function (and it has problem to mix with powermockito2 when testing kotlin etc.) so the powermock is removed.

Tried with mockito-inline 3.8.0

    @Test
    public void test_util_1() {

        String sometext = "sometext";
        try (MockedStatic<Util> utilMoc = Mockito.mockStatic(Util.class)) {
            utilMoc.when(() -> Util.getStringDigest(sometext, "SHA-1", "UTF-8"))
                    .thenReturn(null);

            assertEquals(sometext, Util.generateId(sometext));

        }

got error:

java.lang.AssertionError: Unexpected value 
Expected :sometext
Actual   :null

the Util.generateId(sometext) returns null (not the sometext).

when using assertEquals(sometext, sutilMoc.generateId(sometext)); it cannt compile and says cannt resolve the generateId().

How to use mockito-inline to test the static function?

Or if there is way to mock/stub the depended abstract class MessageDigest for stub the digest() to return null, but dont know is it possible?

1

There are 1 best solutions below

0
On

found a way to make the test work (using .thenCallRealMethod()),

but still not find a way to mock the depended class which is instantiated inside the static function. if anyone knows a solution for that?

    @Test
    public void test_util_1() {

        String sometext = "sometext";
        try (MockedStatic<Util> utilMoc = Mockito.mockStatic(Util.class)) {
            utilMoc.when(() -> Util.getStringDigest(anyString(), anyString(), anyString()))
                    .thenReturn(null);

            // need to tell mock to call the original, otherwise a default mocked stub will be called
            utilMoc.when(() -> Util.generateId(anyString()))
                    .thenCallRealMethod();

            assertEquals(sometext, Util.generateId(sometext));

        }