2012-03-06 6 views
43

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

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

@PrepareForTest(StaticResource.class) 

...

PowerMockito.mockStatic(StaticResource.class); 

...

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

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

Любые идеи?

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

ответ

25

Вы можете сделать это так же, как это делается с 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 

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

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

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


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

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

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

С уважением

+1

, к сожалению, это не будет работать, как при() принимает только переменную и StaticResource тип. ('StaticResource не может быть разрешен переменной ') – Pete

+0

О да, извините, вы правы, мой код ошибочен, я привык к нестационарным издевательствам. Во всяком случае, я обновил свой запрос, чтобы отобразить правильный синтаксис. – Brice

+0

Спасибо! Таким образом, наличие статических вспомогательных методов, не имеющих зависимостей, является плохой идеей? Конечно, я мог бы просто вставлять и возражать, что делает работу, но кажется, что имеет смысл поставить работников, которые не имеют зависимостей в статическом объекте, чтобы обозначить их независимость. – Pete

55

Вы можете окурок статический метод недействительным, как это:

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

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

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

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

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

String resourceName = captor.getValue(); 
+0

Быть в состоянии сделать это довольно круто, поскольку он позволяет вам делать что-то вроде насмешливого Thread.sleep (long millis), чтобы спать в течение другого времени/меньше времени/времени вообще! – fragorl

+0

Есть ли способ избежать использования строк для методов - как «getResource» в вашем примере? –

8

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

StaticClass.method(); 

тогда вы пишете ниже строк кода, чтобы издеваться:

PowerMockito.mockStatic(StaticClass.class); 
PowerMockito.doNothing().when(StaticClass.class); 
StaticClass.method(); 
1

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

Пример кода:

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