如何在Java中模拟ServiceLoader类

时间:2018-09-21 11:32:38

标签: java unit-testing powermock

public class ServiceLoaderDemo {

    public CPService demo() {
        ServiceLoader<CPService> serviceLoader = ServiceLoader.load(CPService.class);
        return iterate(serviceLoader);
    }

    public CPService iterate(ServiceLoader<CPService> serviceLoader) {
        CPService nonDefault = null;
        for (CPService cpService : serviceLoader) {
            cpService.show();
            if(!cpService.isDefault())
            {
                nonDefault = cpService;
            }
        }
        return nonDefault;
    }
}

在以下情况下,我需要为迭代方法编写单元测试:

  1. 默认服务和非默认服务
  2. 仅默认服务
  3. 仅非默认服务
  4. 多个非默认服务

我尝试如下模拟ServiceLoader类:

import static org.fest.reflect.core.Reflection.method;
import static org.powermock.api.mockito.PowerMockito.mock;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ServiceLoader;

import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

import junit.framework.TestCase;

@RunWith(PowerMockRunner.class)
@PrepareForTest(ServiceLoader.class)
public class ServiceLoaderDemoTest extends TestCase {
    private ServiceLoaderDemo serviceLoaderDemo = new ServiceLoaderDemo();

    public void testIterate() {
        final ServiceLoader mockServiceLoader = mock(ServiceLoader.class);
        IteratorDummy iterator = new IteratorDummy();
        iterator.cpServices.add(new CPServiceImplTwo());
        iterator.cpServices.add(new CPServiceImplOne());

        PowerMockito.when(mockServiceLoader.iterator()).thenReturn(iterator);
        CPService methodToTest = null;
        try {
            methodToTest = method("iterate").withReturnType(CPService.class).withParameterTypes(ServiceLoader.class).in(serviceLoaderDemo).invoke(mockServiceLoader);
        } catch (SecurityException e) {
            e.printStackTrace();
        }
        assertEquals(methodToTest.getClass(), ServiceLoaderDemoTest.class);
    }
}

class IteratorDummy implements Iterator<CPService> {
    public List<CPService> cpServices = new ArrayList<>();

    @Override
    public boolean hasNext() {
        return cpServices.iterator().hasNext();
    }

    @Override
    public CPService next() {
        CPService service = cpServices.iterator().next();
        return service;
    }
}

这将引发NullPointerException。我无法为此编写单元测试。请帮助我。

0 个答案:

没有答案