Hot questions for Using Mockito in exception handling
Question:
I have a simple Java
method, I would like to check that it does not throw any exceptions
.
I have already mocked the parameters etc, however I am not sure how to use Mockito
to test that no exception has been thrown from the method?
Current test code:
@Test public void testGetBalanceForPerson() { //creating mock person Person person1 = mock(Person.class); when(person1.getId()).thenReturn("mockedId"); //calling method under test myClass.getBalanceForPerson(person1); //How to check that an exception isn't thrown? }
Answer:
Fail the test if an exception is caught.
@Test public void testGetBalanceForPerson() { // creating mock person Person person1 = mock(Person.class); when(person1.getId()).thenReturn("mockedId"); // calling method under test try { myClass.getBalanceForPerson(person1); } catch(Exception e) { fail("Should not have thrown any exception"); } }
Question:
I'm writing unit test for legacy Java code. Now I'm encountering a problem. Below is the class A
I want to write test code for.
class A { public A(){ } public void doSomething()throws DBException { try{ //some code that might throw JDBCConnectionException }catch(JDBCConnectionException e){ notifyJDBCConnection() }catch(Exception e){ } } private void notifyJDBCConnection(){ //do notification stuff } }
Now say if I need to test whether the method notifyJDBCConnection()
has been executed when JDBCConnectionException
is caught. What is the right way to approach this problem? Or should I just write a test for testing method notifyJDBCConnection
is okay?
Answer:
I presume that notifyJDBCConnection
will call some kind of notification framework, be it an email sender or otherwise. If you mock that component using a framework like Mockito, you can verify that the appropriate calls to said component have been made.
Question:
I'm trying to test the method below with Mockito and Junit:
@Transactional @RequestMapping(method=RequestMethod.PUT,value ="/updateEmployer/{empId}") public @ResponseBody Object updateEmployer(@PathVariable Integer empId,) throws Exception { Employee e = EmployeeRepository.findOne(empId); for (Department de : e.getDepartement()){ de.setDepartmentName(e.getName + "_" + de.getName()); } EmployeeRepository..saveAndFlush(e); return null; }
This is the method Test:
@Test // throw java.lang.NullPointerException public void updateEmployeeFailureTest() throws Exception { mockMvc.perform( MockMvcRequestBuilders .put("/updateEmployer/{empId}",18) .accept(MediaType.APPLICATION_JSON)).andDo(print()) .andExpect(MockMvcResultMatchers.view().name("errorPage")) .andExpect(MockMvcResultMatchers.model().attributeExists("exception")) .andExpect(MockMvcResultMatchers.forwardedUrl("/WEB-INF/jsp/errorPage.jsp")) .andExpect(MockMvcResultMatchers.status().isInternalServerError()); }
The printstack:
MockHttpServletRequest: HTTP Method = PUT Request URI = /updateEmployer/18 Parameters = {} Headers = {Content-Type=[application/json], Accept= application/json]} Handler: Type = com.controllers.employeeController Method = public java.lang.Object com.controllers.employeeController.updateEmployer(java.lang.Integer) throws java.lang.Exception Async: Was async started = false Async result = null Resolved Exception: ***Type = java.lang.NullPointerException*** ModelAndView: View name = errorPage View = null Attribute = exception ***value = java.lang.NullPointerException*** FlashMap: MockHttpServletResponse: Status = 500 Error message = null Headers = {} Content type = null Body = Forwarded URL = /WEB-INF/jsp/errorPage.jsp Redirected URL = null Cookies = []
It's work but when i try to catch the text or the exception throwed by this method adding @Test (expected= java.lang.NullPointerException.class) i have this error:
java.lang.AssertionError: Expected exception: java.lang.NullPointerException
when i try to get the nullPointerException Text as a value of the attribute (exception) of the section ModelAndView i get this error:
java.lang.AssertionError: Model attribute 'exception' expected:java.lang.NullPointerException but was:java.lang.NullPointerException
Is there a way to expect the exception throwed or the text in the value attribut ( value = java.lang.NullPointerException) or the Text in the Resolved Exception section using mockito (mockmvc)?
Any help will be much appreciated
Answer:
You need to test that the exception
attribute of the model is an instance of NullPointerException.
This can be done using a Hamcrest matcher:
.andExpect(MockMvcResultMatchers.model().attribute( "exception", Matchers.isA(NullPointerException.class))
Question:
I am testing a method with an expected exception. I also need to verify that some code was called (on a mocked object) after the exception is thrown, but verification is being ignored. Here is the code:
public class ExceptionHandler { @Autowired private Sender sender; public void handle(Exception exception) throws Exception { if (!SomeException.class.isAssignableFrom(exception.getClass())) { sender.sendMessage(ExceptionUtils.getStackTrace(exception)); } throw exception; } }
Here is the test code:
@Mock private Sender sender; @InjectMocks private ExceptionHandler handler; @Test public void testHandler() throws Exception { SomeException someException = new SomeException(); try { handler.handle(someException); } catch (SomeException thrownResult) { assertEquals(someException, thrownResult); } verify(sender, times(1)).sendMessage(Mockito.anyString()); }
Answer:
I also need to verify that some code was called (on a mocked object) after the exception is thrown, but verification is being ignored.
This is not true, this line is actually executed:
verify(sender, times(1)).sendMessage(Mockito.anyString());
But it fails verification with this error:
Wanted but not invoked: sender.sendMessage();
<...>
Actually, there were zero interactions with this mock.
As expected, that method was never invoked, because condition !SomeException.class.isAssignableFrom(exception.getClass())
was not satisfied - you invoke handler.handle
with instance of SomeException
.
Question:
I want to write unit-test to check work of log.error function when exception is catched. I have this class:
class SalesMasterModelDateSequenceWrapper { public static List<EMDate> getDatesClass(IAnalysisExpressionContext context, IContract contract, EMDate analysisDate, IExpressionLogger log, Lookup lookup) { try { StringBuilder scenarioName = new StringBuilder(); scenarioName.append(contract.getStringFDA(lookup.getServerFDA("NewContractsForecastName").toLowerCase())); if (scenarioName.toString().length()==0) return new ArrayList<>(); scenarioName.append("_").append(analysisDate.year()).append(analysisDate.month()).append(analysisDate.day()); if (!context.getScenarioName().contains(scenarioName.toString())){ return Arrays.asList(contract.getValueDate()); } } catch (Exception e) { StringBuilder sb = new StringBuilder(); sb.append("SalesMasterModelDateSequence: ").append(e.getMessage()).append("\n"); for (StackTraceElement stackTraceElement : e.getStackTrace()) { sb.append(stackTraceElement.toString()).append("\n"); } log.error(sb.toString()); } return new ArrayList<>(); }
I want to verify that I'll take the result of log.error(sb.toString()). Can somebody help with this issue? Thanks in advance.
Answer:
Unse a mocking framework to create a mock of IExpressionLogger
and in your test verify that its error()
method has been called with the expected parameter:
@Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); @Mock private IExpressionLogger expressionLogger; @Mock private Lookup lookup; @Test public void exceptionMessageLoggedAsError() { doThrow(new RuntimeException("UnitTest").when(lookup).getServerFDA(anyString()); new SalesMasterModelDateSequenceWrapper(/* other parameters */,expressionLogger, lookup).getDatesClass(/* parameters */); verify(expressionLogger).error("the expected message containing substring 'UnitTest' from Exception"); }