Как мне издеваться над статическим методом, который возвращает void с PowerMock? - PullRequest
54 голосов
/ 06 марта 2012

В моем проекте есть несколько статических утилит, некоторые из них просто передают или выдают исключение.Существует множество примеров того, как смоделировать статический метод с типом возвращаемого значения, отличным от void.Но как я могу издеваться над статическим методом, который возвращает void просто "doNothing()"?

В не-void версии используются следующие строки кода:

@PrepareForTest(StaticResource.class)

...

PowerMockito.mockStatic(StaticResource.class);

...

Mockito.when(StaticResource.getResource("string")).thenReturn("string");

Однако при применении к StaticResources, который возвращает void, компиляция будет жаловаться, что when(T) не применимо для void ...

Есть идеи?

Обходным путем, вероятно, было бы то, что все статические методы возвращали бы Boolean успеха, но мне не нравятся обходные пути.

Ответы [ 4 ]

71 голосов
/ 02 июля 2013

Вы можете заглушку статический метод void, подобный этому:

PowerMockito.doNothing().when(StaticResource.class, "getResource", anyString());

Хотя я не уверен, почему вы будете беспокоиться, потому что когда вы вызываете mockStatic (StaticResource.class) все статические методы в StaticResource по умолчанию имеют заглушку

Более полезно, вы можете захватить значение, переданное StaticResource.getResource () , например так:

ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
PowerMockito.doNothing().when(
               StaticResource.class, "getResource", captor.capture());

Затем вы можете оценить строку, которая была передана StaticResource.getResource, следующим образом:

String resourceName = captor.getValue();
31 голосов
/ 06 марта 2012

Вы можете сделать это так же, как вы делаете это с Mockito в реальных случаях. Например, вы можете связать заглушки, следующая строка заставит первый вызов ничего не делать, затем второй и будущий вызов getResources сгенерирует исключение:

// the stub of the static method
doNothing().doThrow(Exception.class).when(StaticResource.class);
StaticResource.getResource("string");

// the use of the mocked static code
StaticResource.getResource("string"); // do nothing
StaticResource.getResource("string"); // throw Exception

Благодаря замечанию Мэтта Лахмана, обратите внимание, что если ответ по умолчанию не изменяется во время создания макета, по умолчанию макет ничего не будет делать. Следовательно, написание следующего кода эквивалентно тому, что вы его не пишете.

doNothing().doThrow(Exception.class).when(StaticResource.class);
StaticResource.getResource("string");

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


Кстати, по моему скромному мнению, вам следует избегать насмешливого статического кода, если вы создаете новый код. В Mockito мы думаем, что это, как правило, намек на плохой дизайн, это может привести к плохому обслуживанию кода. Хотя существующий унаследованный код - это еще одна история.

Вообще говоря, если вам нужно смоделировать закрытый или статический метод, то этот метод делает слишком много и его следует выводить из объекта, который будет введен в тестируемый объект.

Надеюсь, это поможет.

Привет

11 голосов
/ 04 мая 2015

Проще говоря, Представьте себе, если вы хотите макет ниже линии:

StaticClass.method();

тогда вы пишете ниже строки кода для макета:

PowerMockito.mockStatic(StaticClass.class);
PowerMockito.doNothing().when(StaticClass.class);
StaticClass.method();
4 голосов
/ 07 июля 2016

Чтобы смоделировать статический метод, который возвращает void, например, Fileutils.forceMKdir(File file),

Пример кода:

File file =PowerMockito.mock(File.class);
PowerMockito.doNothing().when(FileUtils.class,"forceMkdir",file);
...