8

I have written test cases to mock static classes and methods using PowerMockito's mockStatic feature. But I am strugling to mock one static method inside another static method. I did see few examples including this but none of them actually helping me or I am not understanding the actual functionality? (I'm clueless)

Eg. I have a class as below and complete code is here.

public static byte[] encrypt(File file, byte[] publicKey, boolean verify) throws Exception {
        //some logic here
        PGPPublicKey encryptionKey = OpenPgpUtility.readPublicKey(new ByteArrayInputStream(publicKey));
        //some other logic here
}

public/private static PGPPublicKey readPublicKey(InputStream in) throws IOException, PGPException {
 //Impl of this method is here
}

My Test case is:

@Test
    public void testEncrypt() throws Exception {
        File mockFile = Mockito.mock(File.class);
        byte[] publicKey = { 'Z', 'G', 'V', 'j', 'b', '2', 'R', 'l', 'Z', 'F', 'B', 'L', 'Z', 'X', 'k', '=' };
        boolean flag = false;

        PGPPublicKey mockPGPPublicKey = Mockito.mock(PGPPublicKey.class);
        InputStream mockInputStream = Mockito.mock(InputStream.class);

        PowerMockito.mockStatic(OpenPgpUtility.class);

        PowerMockito.when(OpenPgpUtility.readPublicKey(mockInputStream)).thenReturn(mockPGPPublicKey);

        System.out.println("Hashcode for PGPPublicKey: " + OpenPgpUtility.readPublicKey(mockInputStream));
        System.out.println("Hashcode for Encrypt: " + OpenPgpUtility.encrypt(mockFile, publicKey, flag));
    }

When I call OpenPgpUtility.encrypt(mockFile, publicKey, flag) this method is not actually getting called. How Can I mock the result of readPublicKey(...) method in side encrypt(...)?

Community
  • 1
  • 1
Extreme
  • 2,919
  • 1
  • 17
  • 27
  • What method does your class under test use? This is the method you should mock. There is no necessity to mock a private method, since you mock the public interface. – Turing85 May 18 '17 at 17:26
  • I am testing the behavior of `encrypt` method which has the another static method `readPublicKey`. – Extreme May 18 '17 at 17:32
  • And why would you mock a method from the same class? Write tests to test `readPublicKey(...)` and write tests for `encrypt(...)`. It is still the same unit under test and thus no mocking should be used. Mocking is used to eliminate external dependencies to e.g. a database or unknown interface implementations. – Turing85 May 18 '17 at 17:33
  • I am new to unit testing and what I understood is, when I am testing a method's behavior I need to mock all the external dependencies(includes all the methods in same class as well). Am I wrong here? – Extreme May 18 '17 at 17:38
  • Pretty much yes. External dependencies are - external. One class is one unit and should be tested as such. If you write tests for both methods and some "update" will break `readPublicKey`, it is liekly that some tests for both methods will turn red. – Turing85 May 18 '17 at 17:39
  • in such cases, now, I am fixing for that broken/updated method's test cases. – Extreme May 18 '17 at 17:54

1 Answers1

11

I found the solution in SOF in somebody's post.

In my case, I have used same partial mock of PowerMockito as below.

PowerMockito.stub(PowerMockito.method(OpenPgpUtility.class, "readPublicKey", InputStream.class)).toReturn(mockPGPPublicKey);

which letting me to mock readPublicKey() but an actual call to encrypt()

Community
  • 1
  • 1
Extreme
  • 2,919
  • 1
  • 17
  • 27