Consider two classes A
and B
.
class A { static int a(){} }
class B { void something(){ int value=A.a(); .......}}
Now I have to cover class B
using Junit Test case and hence I create a new class (class TestB
) to cover the class B
.
class TestB { @Test public void testsomething(){...} }
Here my question is if there is any way I can cover the line A.a()
as this is the static method. I know that I can't easy mock it because there is no object involved. So how would I proceed?
I am using JUnit and EasyMock.
As you pointed out there is no way to mock a static method with easymock.
Approach 1: Don't use static methods wherever possible.
Approach 2: Use PowerMock on top of easymock.
Approach 3: Delegate the body of A.a()
by using a supplier inside a()
. You can than use a "simple" supplier for testcases and the real world supplier for productive use.
You will have to use PowerMock along with easymock to mock the static methods.
https://github.com/jayway/powermock/wiki/MockStatic
For your test case mock code will look like this
KeyStore aMock = PowerMockito.mock(A.class);
PowerMockito.when(A.a()).thenReturn(0);
Here is a working example to mock static method for KeyStore.getInstance
method
KeyStoreService:
package com.foo;
import java.io.IOException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
public class KeyStoreService {
public KeyStoreService(){
}
public void load() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException{
System.out.println("start");
KeyStore ks = KeyStore.getInstance("");
ks.load(null, null);
System.out.println("end");
}
}
Test class:
package com.foo.test;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.cert.CertificateException;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Matchers;
import org.mockito.Mockito;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import com.foo.KeyStoreService;
@PrepareForTest(KeyStoreService.class)
@RunWith(PowerMockRunner.class)
public class TestKeyStore {
@Test
public void test1() throws KeyStoreException, NoSuchProviderException, NoSuchAlgorithmException, CertificateException, IOException{
PowerMockito.mockStatic(KeyStore.class);
KeyStore keyStoreMock = PowerMockito.mock(KeyStore.class);
KeyStoreService kss = new KeyStoreService();
PowerMockito.when(KeyStore.getInstance(Matchers.anyString(), Matchers.anyString())).thenReturn(keyStoreMock);
Mockito.doNothing().when(keyStoreMock).load(Mockito.any(InputStream.class), Mockito.any(char[].class));
kss.load();
}
}