Powermock не может издеваться над статическим классом - PullRequest
1 голос
/ 19 июня 2019

У меня есть класс с кодом, похожим на:

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), и переключился на JUnit4 для PowerMock.

Я пытался:

@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 () привело меня к тому, когда, но затем выдает ошибку нулевого указателя.

1 Ответ

1 голос
/ 20 июня 2019

Я нашел решение, хотя у меня смешанные чувства по этому поводу.

Используя Util.register (2-й блок кода), я зарегистрировал реализацию службы конфигурации, которая создала фиктивные объекты. Это сработало и позволило мне протестировать метод 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) - лучший из всех, кто знал меня, чтобы проверить, что запуск запускался. Время Mockito / PowerMock (1) потребовало бы макета class1, который, скорее всего, противоречит модульному тесту, чтобы увидеть, МОЖЕТ ли он работать.

...