How to cover a method calling a static method usin

2019-07-26 23:05发布

问题:

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.

回答1:

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.



回答2:

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();
    }
}