Powermock无法模拟静态类

时间:2019-06-19 20:23:23

标签: java unit-testing mockito powermockito

我有一堂课,其代码类似于:

public class class1{
    private static final ConfigurationService config = Util.getInstance(ConfigurationService.class);

    private SendQueueMessages sender;

    public void start() throws LifecycleException{
        LOGGER.info("Starting");

        final ActiveMq activemq = config.getConfiguration().getActiveMq();
        sender = new SendQueueMessages(activemq.getQueueName());
    }
}

在程序的其他地方,Guice用来绑定配置服务和Util,如下所示:

Util.register(new ThingICantChange(){
    @Override
    protected void configure (){
        super.configure();

        bind(ConfigurationService.class).to(ConfigurationServiceImpl.class).asEagerSingleton();
   }
});

这可以进行单元测试吗?最初,我尝试使用JUnit 5和Mockito,但是很明显,我需要模拟静态类/方法(IoCUtils),并切换到PowerMock的JUnit4。

我尝试过:

@RunWith(PowerMockRunner.class)
@PrepareForTest(Util.class)
public class Class1Test{
    @Test
    public void canStart(){
        mockStatic(Util.class);
        when(Util.getInstance(ConfigurationService.class)).thenReturn(new ConfigurationService);
        Class1 class = new Class1();
        class.start();
        //etc.
    }
}

但是,这只是给我一个关于未准备测试的Util的错误。将mockStatic()更改为PowerMockito.spy()确实使我了解了when,但随后抛出了空指针错误。

1 个答案:

答案 0 :(得分:1)

我发现了一个解决方案,尽管对此有好感。

使用Util.register(第二个代码块),我注册了一个创建模拟对象的配置服务实现。这行得通,让我测试了start()方法,但感觉有点与单元测试的想法相反。

public class ConfigServiceTest implements ConfigurationService{

    @Override
    public Configuration getConfiguration() {
        Configuration conf = mock(Configuration.class);
        ActiveMq amq = mock(ActiveMq.class);

        when(amq.getQueueName()).thenReturn("test");
        when(amq.getBrokerUrl()).thenReturn("http://127.0.0.1:61616?soTimeout=1000");
        when(conf.getActiveMq()).thenReturn(amq);

        return conf;
    }
    //other methods just allowed to return null
 }

然后在测试中:

Util.register(new thingICantChange(){
    @Override
    protected void configure (){
        super.configure();
        bind(ConfigurationService.class).to(ConfigServiceTest.class).asEagerSingleton();
    }
});

class1 service = new class1();

service.start();
Assert.assertEquals(true, true);

start是无效的,而不是int一个新线程,因此Assert.assertEquals(true,true)是我周围所知的最好的人,可以检查启动是否运行。 Mockito / PowerMock times(1)需要class1的模拟,这似乎与单元测试相反,以查看其是否可以运行。