Сегодня меня попросили использовать сервис RESTful, поэтому я начал внедрять его, следуя правилам Роберта Сесила Мартина для TDD, и наткнулся на новый (по крайней мере, для меня) способ тестирования ожидаемого исключения вместе с сообщением об ошибке, поэтому подумал о том, чтобы поделиться способом, которым я реализовал это как часть этого поста.
Для начала давайте напишем @Test и определим правило, согласно которому наш код будет генерировать конкретное исключение для нашего примера, это EmployeeServiceException, которое мы проверим с помощью ExpectedException, которое предоставит нам более точную информацию об исключении, которое, как ожидается, будет выдано с возможностью проверки сообщение об ошибке, а именно:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
@RunWith (PowerMockRunner. class ) @PrepareForTest (ClassWithStaticMethod. class ) public class EmployeeServiceImplTest { @InjectMocks private EmployeeServiceImpl employeeServiceImpl; @Rule public ExpectedException expectedException = ExpectedException.none(); @Before public void setupMock() { MockitoAnnotations.initMocks( this ); } @Test public void addEmployeeForNull() throws EmployeeServiceException { expectedException.expect(EmployeeServiceException. class ); expectedException.expectMessage( "Invalid Request" ); employeeServiceImpl.addEmployee( null ); } } |
Теперь мы создадим реализующий класс для нашего @Test, который будет выдавать исключение EmployeeServiceException всякий раз, когда запрос пуст, для меня это EmployeeServiceImpl следующим образом:
EmployeeServiceImpl.java
01
02
03
04
05
06
07
08
09
10
11
|
public class EmployeeServiceImpl implements IEmployeeService { @Override public String addEmployee( final Request request) throws EmployeeServiceException { if (request == null ) { throw new EmployeeServiceException( "Invalid Request" ); } return null ; } } |
Далее мы напишем @Test, в котором мы будем имитировать статический метод, который принимает входные параметры с типом возвращаемого значения, используя PowerMockito.mockStatic () , проверяет его с помощью PowerMockito.verifyStatic () и, наконец, выполняет Assert для записи состояния прохождения теста или сбоя, как показано ниже. :
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
|
@Test public void addEmployee() throws EmployeeServiceException { PowerMockito.mockStatic(ClassWithStaticMethod. class ); PowerMockito.when(ClassWithStaticMethod.getDetails(anyString())) .thenAnswer( new Answer<String>() { @Override public String answer(InvocationOnMock invocation) throws Throwable { Object[] args = invocation.getArguments(); return (String) args[ 0 ]; } }); final String response = employeeServiceImpl.addEmployee( new Request( "Arpit" )); PowerMockito.verifyStatic(); assertThat(response, is( "Arpit" )); } |
Теперь мы предоставим реализацию для нашего @Test внутри EmployeeServiceImpl . Чтобы сделать это, давайте изменим EmployeeServiceImpl, чтобы статический вызов метода был частью инструкции else addEmployee , следующим образом:
01
02
03
04
05
06
07
08
09
10
11
12
|
public class EmployeeServiceImpl implements IEmployeeService { @Override public String addEmployee( final Request request) throws EmployeeServiceException { if (request == null ) { throw new EmployeeServiceException( "Invalid Request" ); } else { return ClassWithStaticMethod.getDetails(request.getName()); } } } |
Где getDetails — статический метод внутри ClassWithStaticMethod :
1
2
3
4
5
6
|
public class ClassWithStaticMethod { public static String getDetails(String name) { return name; } } |
Полный исходный код размещен на github .
Ссылка: | Ожидаемое правило исключения и статические методы насмешки — JUnit от нашего партнера JCG |