Expected Exception Rule and Mocking Static Methods – JUnit
Today I was asked to consume a RESTful service so I started implementing it following Robert Cecil Martin’s rules for TDD and came across a new way (atleast for me) of testing the expected exception along with the error message so thought of sharing the way I implemented it as part of this post.
To start with let’s write a @Test and specify rule that our code will throw a specific exception for our example it’s EmployeeServiceException which we will verify it using ExpectedException which will provide us more precise information about the exception expected to be thrown with the ability to verify error message, as follows:
@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); } }
Now we will create an implementing class for our @Test which will throw EmployeeServiceException whenever the request is null, for me it’s EmployeeServiceImpl as follows:
EmployeeServiceImpl.java
public class EmployeeServiceImpl implements IEmployeeService { @Override public String addEmployee(final Request request) throws EmployeeServiceException { if (request == null) { throw new EmployeeServiceException("Invalid Request"); } return null; } }
Next we will write a @Test where we will mock static method which accepts input parameters with return type using PowerMockito.mockStatic(), verify it using PowerMockito.verifyStatic() and finally do an Assert to record test pass or failure status, as follows:
@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")); }
Now we will provide the implementation for our @Test inside EmployeeServiceImpl itself. To do that, lets modify the EmployeeServiceImpl to have static method call as part of else statement of addEmployee, as follows:
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()); } } }
Where getDetails is a static method inside ClassWithStaticMethod:
public class ClassWithStaticMethod { public static String getDetails(String name) { return name; } }
Complete source code is hosted on github.
Reference: | Expected Exception Rule and Mocking Static Methods – JUnit from our JCG partner Arpit Aggarwal at the Arpit Aggarwal blog. |