PowerMock, где статические методы вызывают статические методы

Коллега пытался написать тест для двух статических методов, где один статический метод вызывал другой.

@RunWith(PowerMockRunner.class)
@PrepareForTest({ ProcessUtil.class, ImageConverter.class })
public class ImageConverterTest {

    private static final Logger log = Logger.getLogger(ImageConverterTest.class.getName());

    @Test
    public void getImageMagicVersion() throws Exception {
        PowerMockito.mockStatic(ProcessUtil.class);

        PowerMockito.when(
                ProcessUtil.execAndReturnResult(Matchers.eq(new String[] { "/usr/bin/convert", "--version" })))
                .thenReturn(OLD_IMAGE_MAGIC);

        String version = ImageConverter.getImageMagicVersion();

        verifyStatic();

        ProcessUtil.execAndReturnResult(new String[] { "/usr/bin/convert", "--version" });

        log.info("Image magic version: " + version);
        assertEquals(version, OLD_IMAGE_MAGIC);
    }
}

OLD_IMAGE_MAGIC — статическая конечная строка.

Когда мы смотрим на ImageConverter.getImageMagicVersion, все, что он делает, это создает массив строк и передает его в ProcessUtil.execAndReturnResult. Если ProcessUtil.execAndReturnResult не издевается и работает, я ожидаю исключения.

Ни ProcessUtil, ни ImageConverter не являются окончательными, они оба являются стандартными классами со всеми статическими методами.

Проблема, которую мы видим, заключается в том, что возвращается версия null, но я также могу проверить вызов статического метода как выполненный и правильный. Когда я вызываю ProcessUtil.execAndReturnResult внутри теста, он возвращает правильное значение.

Используемая версия PowerMock — 1.5.4, и мы используем ее в сочетании с Mockito (хотя это не относится к этому примеру кода) и JUnit 4.11. Любые идеи о том, что мы можем делать неправильно, что может привести к такому результату?


person David H. Clements    schedule 20.02.2014    source источник
comment
почему вы издеваетесь над «ImageConverter», если это класс, который вы хотите протестировать? Кроме того, вы готовите его к насмешке, но никогда не издеваетесь над ним.   -  person iberbeu    schedule 21.02.2014
comment
Они не издеваются над ним, он готовится только для тестирования (вероятно, как часть попытки заставить это работать), но удаление этого не влияет на результат.   -  person David H. Clements    schedule 21.02.2014
comment
Здесь могут произойти две возможные вещи. 1: класс «ProcessUtil» является окончательным и, следовательно, не может быть смоделирован. 2: метод «ProcessUtil.execAndReturnResult» не вызывается с этими точными атрибутами   -  person iberbeu    schedule 21.02.2014
comment
ProcessUtil не является окончательным, и проверка прошла успешно. Если я искажаю аргументы проверки, происходит сбой и выдается ожидаемое сообщение об ошибке. Точно так же сопоставление с any(String[].class) также завершается успешно.   -  person David H. Clements    schedule 21.02.2014


Ответы (1)


Мы определили проблему.

PowerMock рассматривал следующее как другое:

ProcessUtil.execAndReturnResult(String [] values)

а также

ProcessUtil.execAndReturnResult(String... values)

Проблема заключалась в том, что мы использовали не сопоставление varArg, а сопоставление с прямым массивом. Переключение на сопоставитель vararg (или переключение на другой тип данных) устранило проблему.

person David H. Clements    schedule 21.03.2014