简体   繁体   English

Powermock 不能模拟静态类

[英]Powermock can't mock static class

I have a class with code similar to :我有一个类的代码类似于:

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

Elsewhere in the program Guice is being used to bind the configuration service and Util like so:在程序的其他地方使用 Guice 来绑定配置服务和 Util,如下所示:

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

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

Is this possible to unit test?这可以进行单元测试吗? I was initially trying to use JUnit 5 and mockito, but it became apparent that I needed to mock static classes/methods (IoCUtils) and switched to JUnit4 for PowerMock.我最初尝试使用 JUnit 5 和 mockito,但很明显我需要模拟静态类/方法(IoCUtils)并切换到 JUnit4 for PowerMock。

I have tried:我试过了:

@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.
    }
}

However this just gives me an error about Util not prepared for test.然而,这只是给我一个关于 Util 未准备好测试的错误。 Changing mockStatic() to PowerMockito.spy() did get me to the when, but then throws a null pointer error.将 mockStatic() 更改为 PowerMockito.spy() 确实让我知道了何时,但随后会引发空指针错误。

I found a solution, though I have mixed feelings about it.我找到了一个解决方案,尽管我对此感到很复杂。

Using the Util.register (the 2nd code block) I registered a configuration service implementation that created the mock objects.使用 Util.register(第二个代码块)我注册了一个创建模拟对象的配置服务实现。 This worked and let me test the start() method, but feels kind of against the idea of a unit test.这行得通,让我测试 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
 }

Then in the test:然后在测试中:

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 is void and not int a new thread so Assert.assertEquals(true,true) is the best anyone around me knew to check that start ran. start 是无效的,而不是一个新线程,所以 Assert.assertEquals(true,true) 是我周围知道检查 start 运行的最好的人。 Mockito/PowerMock times(1) would require a mock of class1 which seems rather counter to a unit test to see IF it can run. Mockito/PowerMock times(1) 需要对 class1 进行模拟,这似乎与单元测试相反,以查看它是否可以运行。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM