【问题标题】:Powermock can't mock static classPowermock 不能模拟静态类
【发布时间】:2019-06-21 03:20:45
【问题描述】:

我有一个类的代码类似于:

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() 确实让我知道何时,但随后会引发空指针错误。

【问题讨论】:

    标签: java unit-testing mockito powermockito


    【解决方案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 是无效的,而不是一个新线程,所以 Assert.assertEquals(true,true) 是我周围的人所知道的最好的检查 start 运行的人。 Mockito/PowerMock times(1) 需要模拟 class1,这似乎与单元测试相反,以查看它是否可以运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-28
      相关资源
      最近更新 更多